@praxisui/dynamic-form 0.0.1 → 1.0.0-beta.3

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.
@@ -14,7 +14,7 @@ import * as i5$1 from '@angular/material/tooltip';
14
14
  import { MatTooltipModule } from '@angular/material/tooltip';
15
15
  import * as i2$2 from '@angular/material/dialog';
16
16
  import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
17
- import * as i8$2 from '@angular/material/snack-bar';
17
+ import * as i8$3 from '@angular/material/snack-bar';
18
18
  import { MatSnackBarModule } from '@angular/material/snack-bar';
19
19
  import * as i16 from '@angular/material/badge';
20
20
  import { MatBadgeModule } from '@angular/material/badge';
@@ -38,7 +38,7 @@ import * as i10 from '@angular/material/checkbox';
38
38
  import { MatCheckboxModule } from '@angular/material/checkbox';
39
39
  import * as i6$2 from '@angular/material/slide-toggle';
40
40
  import { MatSlideToggleModule } from '@angular/material/slide-toggle';
41
- import * as i12 from '@angular/material/button-toggle';
41
+ import * as i9$1 from '@angular/material/button-toggle';
42
42
  import { MatButtonToggleModule } from '@angular/material/button-toggle';
43
43
  import * as i6$4 from '@praxisui/settings-panel';
44
44
  import { SETTINGS_PANEL_DATA } from '@praxisui/settings-panel';
@@ -55,6 +55,8 @@ import * as i15 from '@angular/material/divider';
55
55
  import { MatDividerModule } from '@angular/material/divider';
56
56
  import * as i3$1 from '@angular/material/expansion';
57
57
  import { MatExpansionModule } from '@angular/material/expansion';
58
+ import * as i8$2 from '@angular/material/toolbar';
59
+ import { MatToolbarModule } from '@angular/material/toolbar';
58
60
  import { CascadeManagerTabComponent } from '@praxisui/metadata-editor';
59
61
  import { DslParser } from '@praxisui/specification';
60
62
 
@@ -869,7 +871,7 @@ class RowConfiguratorComponent {
869
871
  return md;
870
872
  }
871
873
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: RowConfiguratorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
872
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.4", type: RowConfiguratorComponent, isStandalone: true, selector: "praxis-row-configurator", inputs: { row: "row", fieldMetadata: "fieldMetadata", sectionIndex: "sectionIndex", rowIndex: "rowIndex", selected: "selected", availableFieldsListId: "availableFieldsListId", connectedDropListIds: "connectedDropListIds" }, outputs: { rowChange: "rowChange", remove: "remove", fieldDrop: "fieldDrop", select: "select" }, ngImport: i0, template: "<div class=\"row-container\">\n <ng-container *ngIf=\"row.columns.length > 0; else emptyRow\">\n <div\n class=\"row grid-12\"\n cdkDropListGroup\n (click)=\"selectRow()\"\n [class.selected]=\"isRowSelected()\"\n tabindex=\"0\"\n role=\"button\"\n [attr.aria-label]=\"'Linha ' + (rowIndex + 1)\"\n [attr.aria-selected]=\"isRowSelected()\"\n [style.--pfx-grid-gap.px]=\"row.gap || null\"\n [style.marginBottom.px]=\"row.rowGap || null\"\n >\n <div class=\"row-label\" aria-hidden=\"true\">Linha {{ rowIndex + 1 }}</div>\n <div\n *ngFor=\"let column of row.columns; let i = index\"\n class=\"column\"\n [id]=\"getColumnId(i)\"\n cdkDropList\n [cdkDropListData]=\"column.fields\"\n [cdkDropListConnectedTo]=\"connectedColumns(i)\"\n (cdkDropListDropped)=\"drop($event)\"\n (cdkDropListEntered)=\"onDropEnter(i)\"\n (cdkDropListExited)=\"onDropExit(i)\"\n (click)=\"selectColumn(i, $event)\"\n [class.drop-active]=\"activeDropIndex === i\"\n [class.selected]=\"isColumnSelected(i)\"\n [ngClass]=\"getSpanClasses(column)\"\n [style.grid-column]=\"'span ' + getSpanMd(column)\"\n tabindex=\"0\"\n role=\"button\"\n [attr.aria-label]=\"'Coluna ' + (i + 1) + ' de Linha ' + (rowIndex + 1) + '; Largura ' + getSpanMd(column)\"\n [attr.aria-selected]=\"isColumnSelected(i)\"\n >\n <div class=\"column-label\" aria-hidden=\"true\">\n Coluna {{ i + 1 }} \u2022 md={{ getSpanMd(column) }}\n </div>\n <div class=\"column-toolbar\">\n <button\n mat-icon-button\n color=\"warn\"\n (click)=\"removeColumn(i)\"\n matTooltip=\"Remover coluna\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n </div>\n <ng-container *ngIf=\"column.fields.length > 0; else emptyColumn\">\n <div *ngFor=\"let fieldName of column.fields\" (click)=\"selectField(fieldName, $event)\" [class.selected]=\"isFieldSelected(fieldName)\">\n <praxis-field-configurator\n [field]=\"getFieldByName(fieldName)\"\n ></praxis-field-configurator>\n </div>\n </ng-container>\n <ng-template #emptyColumn>\n <div class=\"column-placeholder\">\n <span>Coluna vazia \u2014 solte um campo ou apague.</span>\n </div>\n </ng-template>\n </div>\n </div>\n <div class=\"row-actions\">\n <button mat-icon-button [matMenuTriggerFor]=\"rowMenu\" matTooltip=\"Op\u00E7\u00F5es da linha\">\n <mat-icon>more_vert</mat-icon>\n </button>\n <mat-menu #rowMenu=\"matMenu\">\n <div mat-menu-item disabled>Presets de colunas</div>\n <button mat-menu-item (click)=\"applyPreset([12])\"><mat-icon>view_column</mat-icon><span>1/1</span></button>\n <button mat-menu-item (click)=\"applyPreset([6,6])\"><mat-icon>view_column</mat-icon><span>1/2 \u2014 1/2</span></button>\n <button mat-menu-item (click)=\"applyPreset([4,8])\"><mat-icon>view_column</mat-icon><span>1/3 \u2014 2/3</span></button>\n <button mat-menu-item (click)=\"applyPreset([8,4])\"><mat-icon>view_column</mat-icon><span>2/3 \u2014 1/3</span></button>\n <button mat-menu-item (click)=\"applyPreset([4,4,4])\"><mat-icon>view_column</mat-icon><span>1/3 \u2014 1/3 \u2014 1/3</span></button>\n <button mat-menu-item (click)=\"applyPreset([3,3,3,3])\"><mat-icon>view_column</mat-icon><span>1/4 \u2014 1/4 \u2014 1/4 \u2014 1/4</span></button>\n <button mat-menu-item (click)=\"addColumn()\"><mat-icon>add</mat-icon><span>Adicionar coluna</span></button>\n <button mat-menu-item (click)=\"removeRow()\"><mat-icon>delete</mat-icon><span>Remover linha</span></button>\n </mat-menu>\n </div>\n </ng-container>\n <ng-template #emptyRow>\n <div class=\"row-empty-placeholder\">\n <span>Linha vazia \u2014 crie colunas ou apague.</span>\n <div class=\"row-placeholder-actions\">\n <button\n mat-stroked-button\n (click)=\"addColumn()\"\n matTooltip=\"Adicionar coluna\"\n >\n <mat-icon>add</mat-icon> Add coluna\n </button>\n <button\n mat-stroked-button\n color=\"warn\"\n (click)=\"removeRow()\"\n matTooltip=\"Remover linha\"\n >\n <mat-icon>delete</mat-icon> Apagar Linha\n </button>\n </div>\n </div>\n </ng-template>\n</div>\n", styles: [".row-container{position:relative;display:flex;align-items:stretch}.row{display:flex;flex-grow:1;position:relative;padding-right:56px;border-radius:6px;transition:box-shadow .2s ease}.row:focus{outline:none;box-shadow:0 0 0 2px color-mix(in oklab,var(--md-sys-color-primary) 35%,transparent)}.row.grid-12{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:var(--pfx-grid-gap, 16px)}.row.selected{box-shadow:0 0 0 2px color-mix(in oklab,var(--md-sys-color-primary) 30%,transparent)}.row-label{position:absolute;left:-4px;top:-10px;transform:translateY(-100%);background:color-mix(in oklab,var(--md-sys-color-surface-variant) 80%,transparent);color:var(--md-sys-color-on-surface-variant);border:1px solid var(--md-sys-color-outline-variant);border-radius:10px;padding:2px 6px;font-size:11px;opacity:0;transition:opacity .15s ease;pointer-events:none}.row:hover .row-label,.row.selected .row-label{opacity:1}.column{position:relative;flex:1;display:grid;align-content:start;gap:6px;border:1px dashed var(--md-sys-color-outline-variant);margin:4px;padding:6px;min-height:50px;background:var(--md-sys-color-surface-container);transition:background-color .2s ease,border-color .2s ease}.row.grid-12 .column{flex:unset}.column>div{margin:0}.column:focus{outline:none;box-shadow:0 0 0 2px color-mix(in oklab,var(--md-sys-color-primary) 35%,transparent)}.column.drop-active{border-color:var(--md-sys-color-primary);background:var(--md-sys-color-surface-variant)}.column.selected{border-color:var(--md-sys-color-primary);box-shadow:0 0 0 2px color-mix(in oklab,var(--md-sys-color-primary) 30%,transparent)}.column.cdk-drop-list-receiving{animation:columnHighlight .3s ease-in-out}.column-label{position:absolute;top:-8px;left:8px;transform:translateY(-100%);background:color-mix(in oklab,var(--md-sys-color-surface-variant) 80%,transparent);color:var(--md-sys-color-on-surface-variant);border:1px solid var(--md-sys-color-outline-variant);border-radius:10px;padding:2px 6px;font-size:11px;opacity:0;transition:opacity .15s ease;pointer-events:none}.column:hover .column-label,.column.selected .column-label{opacity:1}@keyframes columnHighlight{0%{box-shadow:0 0 0 2px var(--md-sys-color-primary)}to{box-shadow:none}}.column-toolbar{position:absolute;top:8px;right:8px;display:flex;gap:4px;opacity:0;transition:opacity .2s ease}.column:hover .column-toolbar,.column:focus .column-toolbar,.column.selected .column-toolbar{opacity:1}.column-placeholder{display:flex;flex-direction:column;align-items:center;justify-content:center;color:var(--md-sys-color-on-surface-variant);height:100%;text-align:center}.row-actions{position:absolute;right:8px;top:8px;transform:none;display:flex;flex-direction:column;gap:6px;align-items:center;pointer-events:auto;opacity:0;transition:opacity .15s ease;z-index:3}.row-container:hover .row-actions,.row.selected+.row-actions,.row-actions:focus-within{opacity:1}.field-selected-highlight.selected .field-item,.selected>.field-item{border-color:var(--md-sys-color-primary)!important;box-shadow:0 0 0 2px color-mix(in oklab,var(--md-sys-color-primary) 30%,transparent)}.row-empty-placeholder{flex:1;border:1px dashed var(--md-sys-color-outline-variant);margin:4px;padding:16px;text-align:center;color:var(--md-sys-color-on-surface-variant);background:var(--md-sys-color-surface-container)}.row-placeholder-actions{margin-top:8px;display:flex;gap:8px;justify-content:center}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i2$1.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i2$1.CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "component", type: FieldConfiguratorComponent, selector: "praxis-field-configurator", inputs: ["field"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.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: i3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i5$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i6$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: i6$1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i6$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }] });
874
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.4", type: RowConfiguratorComponent, isStandalone: true, selector: "praxis-row-configurator", inputs: { row: "row", fieldMetadata: "fieldMetadata", sectionIndex: "sectionIndex", rowIndex: "rowIndex", selected: "selected", availableFieldsListId: "availableFieldsListId", connectedDropListIds: "connectedDropListIds" }, outputs: { rowChange: "rowChange", remove: "remove", fieldDrop: "fieldDrop", select: "select" }, ngImport: i0, template: "<div class=\"row-container\">\n <ng-container *ngIf=\"row.columns.length > 0; else emptyRow\">\n <div\n class=\"row grid-12\"\n cdkDropListGroup\n (click)=\"selectRow()\"\n [class.selected]=\"isRowSelected()\"\n tabindex=\"0\"\n role=\"button\"\n [attr.aria-label]=\"'Linha ' + (rowIndex + 1)\"\n [attr.aria-selected]=\"isRowSelected()\"\n [style.--pfx-grid-gap.px]=\"row.gap || null\"\n [style.marginBottom.px]=\"row.rowGap || null\"\n >\n <div class=\"row-label\" aria-hidden=\"true\">Linha {{ rowIndex + 1 }}</div>\n <div\n *ngFor=\"let column of row.columns; let i = index\"\n class=\"column\"\n [id]=\"getColumnId(i)\"\n cdkDropList\n [cdkDropListData]=\"column.fields\"\n [cdkDropListConnectedTo]=\"connectedColumns(i)\"\n (cdkDropListDropped)=\"drop($event)\"\n (cdkDropListEntered)=\"onDropEnter(i)\"\n (cdkDropListExited)=\"onDropExit(i)\"\n (click)=\"selectColumn(i, $event)\"\n [class.drop-active]=\"activeDropIndex === i\"\n [class.selected]=\"isColumnSelected(i)\"\n [ngClass]=\"getSpanClasses(column)\"\n [style.grid-column]=\"'span ' + getSpanMd(column)\"\n tabindex=\"0\"\n role=\"button\"\n [attr.aria-label]=\"'Coluna ' + (i + 1) + ' de Linha ' + (rowIndex + 1) + '; Largura ' + getSpanMd(column)\"\n [attr.aria-selected]=\"isColumnSelected(i)\"\n >\n <div class=\"column-label\" aria-hidden=\"true\">\n Coluna {{ i + 1 }} \u2022 md={{ getSpanMd(column) }}\n </div>\n <div class=\"column-toolbar\">\n <button\n mat-icon-button\n color=\"warn\"\n (click)=\"removeColumn(i)\"\n matTooltip=\"Remover coluna\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n </div>\n <ng-container *ngIf=\"column.fields.length > 0; else emptyColumn\">\n <div *ngFor=\"let fieldName of column.fields\" (click)=\"selectField(fieldName, $event)\" [class.selected]=\"isFieldSelected(fieldName)\">\n <praxis-field-configurator\n [field]=\"getFieldByName(fieldName)\"\n ></praxis-field-configurator>\n </div>\n </ng-container>\n <ng-template #emptyColumn>\n <div class=\"column-placeholder\">\n <span>Coluna vazia \u2014 solte um campo ou apague.</span>\n </div>\n </ng-template>\n </div>\n </div>\n <div class=\"row-actions\">\n <button mat-icon-button [matMenuTriggerFor]=\"rowMenu\" matTooltip=\"Op\u00E7\u00F5es da linha\">\n <mat-icon>more_vert</mat-icon>\n </button>\n <mat-menu #rowMenu=\"matMenu\">\n <div mat-menu-item disabled>Presets de colunas</div>\n <button mat-menu-item (click)=\"applyPreset([12])\"><mat-icon>view_column</mat-icon><span>1/1</span></button>\n <button mat-menu-item (click)=\"applyPreset([6,6])\"><mat-icon>view_column</mat-icon><span>1/2 \u2014 1/2</span></button>\n <button mat-menu-item (click)=\"applyPreset([4,8])\"><mat-icon>view_column</mat-icon><span>1/3 \u2014 2/3</span></button>\n <button mat-menu-item (click)=\"applyPreset([8,4])\"><mat-icon>view_column</mat-icon><span>2/3 \u2014 1/3</span></button>\n <button mat-menu-item (click)=\"applyPreset([4,4,4])\"><mat-icon>view_column</mat-icon><span>1/3 \u2014 1/3 \u2014 1/3</span></button>\n <button mat-menu-item (click)=\"applyPreset([3,3,3,3])\"><mat-icon>view_column</mat-icon><span>1/4 \u2014 1/4 \u2014 1/4 \u2014 1/4</span></button>\n <button mat-menu-item (click)=\"addColumn()\"><mat-icon>add</mat-icon><span>Adicionar coluna</span></button>\n <button mat-menu-item (click)=\"removeRow()\"><mat-icon>delete</mat-icon><span>Remover linha</span></button>\n </mat-menu>\n </div>\n </ng-container>\n <ng-template #emptyRow>\n <div class=\"row-empty-placeholder\">\n <span>Linha vazia \u2014 crie colunas ou apague.</span>\n <div class=\"row-placeholder-actions\">\n <button\n mat-stroked-button\n (click)=\"addColumn()\"\n matTooltip=\"Adicionar coluna\"\n >\n <mat-icon>add</mat-icon> Add coluna\n </button>\n <button\n mat-stroked-button\n color=\"warn\"\n (click)=\"removeRow()\"\n matTooltip=\"Remover linha\"\n >\n <mat-icon>delete</mat-icon> Apagar Linha\n </button>\n </div>\n </div>\n </ng-template>\n</div>\n", styles: [".row-container{position:relative;display:flex;align-items:stretch}.row{display:flex;flex-grow:1;position:relative;padding-right:56px;border-radius:6px;transition:box-shadow .2s ease;gap:var(--pfx-grid-gap, 12px)}.row:focus{outline:none;box-shadow:0 0 0 2px color-mix(in oklab,var(--md-sys-color-primary) 35%,transparent)}.row.grid-12{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:var(--pfx-grid-gap, 16px)}.row.selected{box-shadow:0 0 0 2px color-mix(in oklab,var(--md-sys-color-primary) 30%,transparent)}.row-label{position:absolute;left:-4px;top:-10px;transform:translateY(-100%);background:color-mix(in oklab,var(--md-sys-color-surface-variant) 80%,transparent);color:var(--md-sys-color-on-surface-variant);border:1px solid var(--md-sys-color-outline-variant);border-radius:10px;padding:2px 6px;font-size:11px;opacity:0;transition:opacity .15s ease;pointer-events:none}.row:hover .row-label,.row.selected .row-label{opacity:1}.column{position:relative;flex:1;display:grid;align-content:start;gap:6px;border:1px dashed var(--md-sys-color-outline-variant);margin:0;padding:6px;min-height:50px;background:var(--md-sys-color-surface-container);transition:background-color .2s ease,border-color .2s ease}.row.grid-12 .column{flex:unset}.column>div{margin:0}.column:focus{outline:none;box-shadow:0 0 0 2px color-mix(in oklab,var(--md-sys-color-primary) 35%,transparent)}.column.drop-active{border-color:var(--md-sys-color-primary);background:var(--md-sys-color-surface-variant)}.column.selected{border-color:var(--md-sys-color-primary);box-shadow:0 0 0 2px color-mix(in oklab,var(--md-sys-color-primary) 30%,transparent)}.column.cdk-drop-list-receiving{animation:columnHighlight .3s ease-in-out}.column-label{position:absolute;top:-8px;left:8px;transform:translateY(-100%);background:color-mix(in oklab,var(--md-sys-color-surface-variant) 80%,transparent);color:var(--md-sys-color-on-surface-variant);border:1px solid var(--md-sys-color-outline-variant);border-radius:10px;padding:2px 6px;font-size:11px;opacity:0;transition:opacity .15s ease;pointer-events:none}.column:hover .column-label,.column.selected .column-label{opacity:1}@keyframes columnHighlight{0%{box-shadow:0 0 0 2px var(--md-sys-color-primary)}to{box-shadow:none}}.column-toolbar{position:absolute;top:8px;right:8px;display:flex;gap:4px;opacity:0;transition:opacity .2s ease}.column:hover .column-toolbar,.column:focus .column-toolbar,.column.selected .column-toolbar{opacity:1}.column-placeholder{display:flex;flex-direction:column;align-items:center;justify-content:center;color:var(--md-sys-color-on-surface-variant);height:100%;text-align:center}.row-actions{position:absolute;right:8px;top:8px;transform:none;display:flex;flex-direction:column;gap:6px;align-items:center;pointer-events:auto;opacity:0;transition:opacity .15s ease;z-index:3}.row-container:hover .row-actions,.row.selected+.row-actions,.row-actions:focus-within{opacity:1}.field-selected-highlight.selected .field-item,.selected>.field-item{border-color:var(--md-sys-color-primary)!important;box-shadow:0 0 0 2px color-mix(in oklab,var(--md-sys-color-primary) 30%,transparent)}.row-empty-placeholder{flex:1;border:1px dashed var(--md-sys-color-outline-variant);margin:0;padding:16px;text-align:center;color:var(--md-sys-color-on-surface-variant);background:var(--md-sys-color-surface-container)}.row-placeholder-actions{margin-top:8px;display:flex;gap:8px;justify-content:center}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i2$1.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i2$1.CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "component", type: FieldConfiguratorComponent, selector: "praxis-field-configurator", inputs: ["field"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.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: i3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i5$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i6$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: i6$1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i6$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }] });
873
875
  }
874
876
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: RowConfiguratorComponent, decorators: [{
875
877
  type: Component,
@@ -881,7 +883,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImpor
881
883
  MatIconModule,
882
884
  MatTooltipModule,
883
885
  MatMenuModule,
884
- ], template: "<div class=\"row-container\">\n <ng-container *ngIf=\"row.columns.length > 0; else emptyRow\">\n <div\n class=\"row grid-12\"\n cdkDropListGroup\n (click)=\"selectRow()\"\n [class.selected]=\"isRowSelected()\"\n tabindex=\"0\"\n role=\"button\"\n [attr.aria-label]=\"'Linha ' + (rowIndex + 1)\"\n [attr.aria-selected]=\"isRowSelected()\"\n [style.--pfx-grid-gap.px]=\"row.gap || null\"\n [style.marginBottom.px]=\"row.rowGap || null\"\n >\n <div class=\"row-label\" aria-hidden=\"true\">Linha {{ rowIndex + 1 }}</div>\n <div\n *ngFor=\"let column of row.columns; let i = index\"\n class=\"column\"\n [id]=\"getColumnId(i)\"\n cdkDropList\n [cdkDropListData]=\"column.fields\"\n [cdkDropListConnectedTo]=\"connectedColumns(i)\"\n (cdkDropListDropped)=\"drop($event)\"\n (cdkDropListEntered)=\"onDropEnter(i)\"\n (cdkDropListExited)=\"onDropExit(i)\"\n (click)=\"selectColumn(i, $event)\"\n [class.drop-active]=\"activeDropIndex === i\"\n [class.selected]=\"isColumnSelected(i)\"\n [ngClass]=\"getSpanClasses(column)\"\n [style.grid-column]=\"'span ' + getSpanMd(column)\"\n tabindex=\"0\"\n role=\"button\"\n [attr.aria-label]=\"'Coluna ' + (i + 1) + ' de Linha ' + (rowIndex + 1) + '; Largura ' + getSpanMd(column)\"\n [attr.aria-selected]=\"isColumnSelected(i)\"\n >\n <div class=\"column-label\" aria-hidden=\"true\">\n Coluna {{ i + 1 }} \u2022 md={{ getSpanMd(column) }}\n </div>\n <div class=\"column-toolbar\">\n <button\n mat-icon-button\n color=\"warn\"\n (click)=\"removeColumn(i)\"\n matTooltip=\"Remover coluna\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n </div>\n <ng-container *ngIf=\"column.fields.length > 0; else emptyColumn\">\n <div *ngFor=\"let fieldName of column.fields\" (click)=\"selectField(fieldName, $event)\" [class.selected]=\"isFieldSelected(fieldName)\">\n <praxis-field-configurator\n [field]=\"getFieldByName(fieldName)\"\n ></praxis-field-configurator>\n </div>\n </ng-container>\n <ng-template #emptyColumn>\n <div class=\"column-placeholder\">\n <span>Coluna vazia \u2014 solte um campo ou apague.</span>\n </div>\n </ng-template>\n </div>\n </div>\n <div class=\"row-actions\">\n <button mat-icon-button [matMenuTriggerFor]=\"rowMenu\" matTooltip=\"Op\u00E7\u00F5es da linha\">\n <mat-icon>more_vert</mat-icon>\n </button>\n <mat-menu #rowMenu=\"matMenu\">\n <div mat-menu-item disabled>Presets de colunas</div>\n <button mat-menu-item (click)=\"applyPreset([12])\"><mat-icon>view_column</mat-icon><span>1/1</span></button>\n <button mat-menu-item (click)=\"applyPreset([6,6])\"><mat-icon>view_column</mat-icon><span>1/2 \u2014 1/2</span></button>\n <button mat-menu-item (click)=\"applyPreset([4,8])\"><mat-icon>view_column</mat-icon><span>1/3 \u2014 2/3</span></button>\n <button mat-menu-item (click)=\"applyPreset([8,4])\"><mat-icon>view_column</mat-icon><span>2/3 \u2014 1/3</span></button>\n <button mat-menu-item (click)=\"applyPreset([4,4,4])\"><mat-icon>view_column</mat-icon><span>1/3 \u2014 1/3 \u2014 1/3</span></button>\n <button mat-menu-item (click)=\"applyPreset([3,3,3,3])\"><mat-icon>view_column</mat-icon><span>1/4 \u2014 1/4 \u2014 1/4 \u2014 1/4</span></button>\n <button mat-menu-item (click)=\"addColumn()\"><mat-icon>add</mat-icon><span>Adicionar coluna</span></button>\n <button mat-menu-item (click)=\"removeRow()\"><mat-icon>delete</mat-icon><span>Remover linha</span></button>\n </mat-menu>\n </div>\n </ng-container>\n <ng-template #emptyRow>\n <div class=\"row-empty-placeholder\">\n <span>Linha vazia \u2014 crie colunas ou apague.</span>\n <div class=\"row-placeholder-actions\">\n <button\n mat-stroked-button\n (click)=\"addColumn()\"\n matTooltip=\"Adicionar coluna\"\n >\n <mat-icon>add</mat-icon> Add coluna\n </button>\n <button\n mat-stroked-button\n color=\"warn\"\n (click)=\"removeRow()\"\n matTooltip=\"Remover linha\"\n >\n <mat-icon>delete</mat-icon> Apagar Linha\n </button>\n </div>\n </div>\n </ng-template>\n</div>\n", styles: [".row-container{position:relative;display:flex;align-items:stretch}.row{display:flex;flex-grow:1;position:relative;padding-right:56px;border-radius:6px;transition:box-shadow .2s ease}.row:focus{outline:none;box-shadow:0 0 0 2px color-mix(in oklab,var(--md-sys-color-primary) 35%,transparent)}.row.grid-12{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:var(--pfx-grid-gap, 16px)}.row.selected{box-shadow:0 0 0 2px color-mix(in oklab,var(--md-sys-color-primary) 30%,transparent)}.row-label{position:absolute;left:-4px;top:-10px;transform:translateY(-100%);background:color-mix(in oklab,var(--md-sys-color-surface-variant) 80%,transparent);color:var(--md-sys-color-on-surface-variant);border:1px solid var(--md-sys-color-outline-variant);border-radius:10px;padding:2px 6px;font-size:11px;opacity:0;transition:opacity .15s ease;pointer-events:none}.row:hover .row-label,.row.selected .row-label{opacity:1}.column{position:relative;flex:1;display:grid;align-content:start;gap:6px;border:1px dashed var(--md-sys-color-outline-variant);margin:4px;padding:6px;min-height:50px;background:var(--md-sys-color-surface-container);transition:background-color .2s ease,border-color .2s ease}.row.grid-12 .column{flex:unset}.column>div{margin:0}.column:focus{outline:none;box-shadow:0 0 0 2px color-mix(in oklab,var(--md-sys-color-primary) 35%,transparent)}.column.drop-active{border-color:var(--md-sys-color-primary);background:var(--md-sys-color-surface-variant)}.column.selected{border-color:var(--md-sys-color-primary);box-shadow:0 0 0 2px color-mix(in oklab,var(--md-sys-color-primary) 30%,transparent)}.column.cdk-drop-list-receiving{animation:columnHighlight .3s ease-in-out}.column-label{position:absolute;top:-8px;left:8px;transform:translateY(-100%);background:color-mix(in oklab,var(--md-sys-color-surface-variant) 80%,transparent);color:var(--md-sys-color-on-surface-variant);border:1px solid var(--md-sys-color-outline-variant);border-radius:10px;padding:2px 6px;font-size:11px;opacity:0;transition:opacity .15s ease;pointer-events:none}.column:hover .column-label,.column.selected .column-label{opacity:1}@keyframes columnHighlight{0%{box-shadow:0 0 0 2px var(--md-sys-color-primary)}to{box-shadow:none}}.column-toolbar{position:absolute;top:8px;right:8px;display:flex;gap:4px;opacity:0;transition:opacity .2s ease}.column:hover .column-toolbar,.column:focus .column-toolbar,.column.selected .column-toolbar{opacity:1}.column-placeholder{display:flex;flex-direction:column;align-items:center;justify-content:center;color:var(--md-sys-color-on-surface-variant);height:100%;text-align:center}.row-actions{position:absolute;right:8px;top:8px;transform:none;display:flex;flex-direction:column;gap:6px;align-items:center;pointer-events:auto;opacity:0;transition:opacity .15s ease;z-index:3}.row-container:hover .row-actions,.row.selected+.row-actions,.row-actions:focus-within{opacity:1}.field-selected-highlight.selected .field-item,.selected>.field-item{border-color:var(--md-sys-color-primary)!important;box-shadow:0 0 0 2px color-mix(in oklab,var(--md-sys-color-primary) 30%,transparent)}.row-empty-placeholder{flex:1;border:1px dashed var(--md-sys-color-outline-variant);margin:4px;padding:16px;text-align:center;color:var(--md-sys-color-on-surface-variant);background:var(--md-sys-color-surface-container)}.row-placeholder-actions{margin-top:8px;display:flex;gap:8px;justify-content:center}\n"] }]
886
+ ], template: "<div class=\"row-container\">\n <ng-container *ngIf=\"row.columns.length > 0; else emptyRow\">\n <div\n class=\"row grid-12\"\n cdkDropListGroup\n (click)=\"selectRow()\"\n [class.selected]=\"isRowSelected()\"\n tabindex=\"0\"\n role=\"button\"\n [attr.aria-label]=\"'Linha ' + (rowIndex + 1)\"\n [attr.aria-selected]=\"isRowSelected()\"\n [style.--pfx-grid-gap.px]=\"row.gap || null\"\n [style.marginBottom.px]=\"row.rowGap || null\"\n >\n <div class=\"row-label\" aria-hidden=\"true\">Linha {{ rowIndex + 1 }}</div>\n <div\n *ngFor=\"let column of row.columns; let i = index\"\n class=\"column\"\n [id]=\"getColumnId(i)\"\n cdkDropList\n [cdkDropListData]=\"column.fields\"\n [cdkDropListConnectedTo]=\"connectedColumns(i)\"\n (cdkDropListDropped)=\"drop($event)\"\n (cdkDropListEntered)=\"onDropEnter(i)\"\n (cdkDropListExited)=\"onDropExit(i)\"\n (click)=\"selectColumn(i, $event)\"\n [class.drop-active]=\"activeDropIndex === i\"\n [class.selected]=\"isColumnSelected(i)\"\n [ngClass]=\"getSpanClasses(column)\"\n [style.grid-column]=\"'span ' + getSpanMd(column)\"\n tabindex=\"0\"\n role=\"button\"\n [attr.aria-label]=\"'Coluna ' + (i + 1) + ' de Linha ' + (rowIndex + 1) + '; Largura ' + getSpanMd(column)\"\n [attr.aria-selected]=\"isColumnSelected(i)\"\n >\n <div class=\"column-label\" aria-hidden=\"true\">\n Coluna {{ i + 1 }} \u2022 md={{ getSpanMd(column) }}\n </div>\n <div class=\"column-toolbar\">\n <button\n mat-icon-button\n color=\"warn\"\n (click)=\"removeColumn(i)\"\n matTooltip=\"Remover coluna\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n </div>\n <ng-container *ngIf=\"column.fields.length > 0; else emptyColumn\">\n <div *ngFor=\"let fieldName of column.fields\" (click)=\"selectField(fieldName, $event)\" [class.selected]=\"isFieldSelected(fieldName)\">\n <praxis-field-configurator\n [field]=\"getFieldByName(fieldName)\"\n ></praxis-field-configurator>\n </div>\n </ng-container>\n <ng-template #emptyColumn>\n <div class=\"column-placeholder\">\n <span>Coluna vazia \u2014 solte um campo ou apague.</span>\n </div>\n </ng-template>\n </div>\n </div>\n <div class=\"row-actions\">\n <button mat-icon-button [matMenuTriggerFor]=\"rowMenu\" matTooltip=\"Op\u00E7\u00F5es da linha\">\n <mat-icon>more_vert</mat-icon>\n </button>\n <mat-menu #rowMenu=\"matMenu\">\n <div mat-menu-item disabled>Presets de colunas</div>\n <button mat-menu-item (click)=\"applyPreset([12])\"><mat-icon>view_column</mat-icon><span>1/1</span></button>\n <button mat-menu-item (click)=\"applyPreset([6,6])\"><mat-icon>view_column</mat-icon><span>1/2 \u2014 1/2</span></button>\n <button mat-menu-item (click)=\"applyPreset([4,8])\"><mat-icon>view_column</mat-icon><span>1/3 \u2014 2/3</span></button>\n <button mat-menu-item (click)=\"applyPreset([8,4])\"><mat-icon>view_column</mat-icon><span>2/3 \u2014 1/3</span></button>\n <button mat-menu-item (click)=\"applyPreset([4,4,4])\"><mat-icon>view_column</mat-icon><span>1/3 \u2014 1/3 \u2014 1/3</span></button>\n <button mat-menu-item (click)=\"applyPreset([3,3,3,3])\"><mat-icon>view_column</mat-icon><span>1/4 \u2014 1/4 \u2014 1/4 \u2014 1/4</span></button>\n <button mat-menu-item (click)=\"addColumn()\"><mat-icon>add</mat-icon><span>Adicionar coluna</span></button>\n <button mat-menu-item (click)=\"removeRow()\"><mat-icon>delete</mat-icon><span>Remover linha</span></button>\n </mat-menu>\n </div>\n </ng-container>\n <ng-template #emptyRow>\n <div class=\"row-empty-placeholder\">\n <span>Linha vazia \u2014 crie colunas ou apague.</span>\n <div class=\"row-placeholder-actions\">\n <button\n mat-stroked-button\n (click)=\"addColumn()\"\n matTooltip=\"Adicionar coluna\"\n >\n <mat-icon>add</mat-icon> Add coluna\n </button>\n <button\n mat-stroked-button\n color=\"warn\"\n (click)=\"removeRow()\"\n matTooltip=\"Remover linha\"\n >\n <mat-icon>delete</mat-icon> Apagar Linha\n </button>\n </div>\n </div>\n </ng-template>\n</div>\n", styles: [".row-container{position:relative;display:flex;align-items:stretch}.row{display:flex;flex-grow:1;position:relative;padding-right:56px;border-radius:6px;transition:box-shadow .2s ease;gap:var(--pfx-grid-gap, 12px)}.row:focus{outline:none;box-shadow:0 0 0 2px color-mix(in oklab,var(--md-sys-color-primary) 35%,transparent)}.row.grid-12{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:var(--pfx-grid-gap, 16px)}.row.selected{box-shadow:0 0 0 2px color-mix(in oklab,var(--md-sys-color-primary) 30%,transparent)}.row-label{position:absolute;left:-4px;top:-10px;transform:translateY(-100%);background:color-mix(in oklab,var(--md-sys-color-surface-variant) 80%,transparent);color:var(--md-sys-color-on-surface-variant);border:1px solid var(--md-sys-color-outline-variant);border-radius:10px;padding:2px 6px;font-size:11px;opacity:0;transition:opacity .15s ease;pointer-events:none}.row:hover .row-label,.row.selected .row-label{opacity:1}.column{position:relative;flex:1;display:grid;align-content:start;gap:6px;border:1px dashed var(--md-sys-color-outline-variant);margin:0;padding:6px;min-height:50px;background:var(--md-sys-color-surface-container);transition:background-color .2s ease,border-color .2s ease}.row.grid-12 .column{flex:unset}.column>div{margin:0}.column:focus{outline:none;box-shadow:0 0 0 2px color-mix(in oklab,var(--md-sys-color-primary) 35%,transparent)}.column.drop-active{border-color:var(--md-sys-color-primary);background:var(--md-sys-color-surface-variant)}.column.selected{border-color:var(--md-sys-color-primary);box-shadow:0 0 0 2px color-mix(in oklab,var(--md-sys-color-primary) 30%,transparent)}.column.cdk-drop-list-receiving{animation:columnHighlight .3s ease-in-out}.column-label{position:absolute;top:-8px;left:8px;transform:translateY(-100%);background:color-mix(in oklab,var(--md-sys-color-surface-variant) 80%,transparent);color:var(--md-sys-color-on-surface-variant);border:1px solid var(--md-sys-color-outline-variant);border-radius:10px;padding:2px 6px;font-size:11px;opacity:0;transition:opacity .15s ease;pointer-events:none}.column:hover .column-label,.column.selected .column-label{opacity:1}@keyframes columnHighlight{0%{box-shadow:0 0 0 2px var(--md-sys-color-primary)}to{box-shadow:none}}.column-toolbar{position:absolute;top:8px;right:8px;display:flex;gap:4px;opacity:0;transition:opacity .2s ease}.column:hover .column-toolbar,.column:focus .column-toolbar,.column.selected .column-toolbar{opacity:1}.column-placeholder{display:flex;flex-direction:column;align-items:center;justify-content:center;color:var(--md-sys-color-on-surface-variant);height:100%;text-align:center}.row-actions{position:absolute;right:8px;top:8px;transform:none;display:flex;flex-direction:column;gap:6px;align-items:center;pointer-events:auto;opacity:0;transition:opacity .15s ease;z-index:3}.row-container:hover .row-actions,.row.selected+.row-actions,.row-actions:focus-within{opacity:1}.field-selected-highlight.selected .field-item,.selected>.field-item{border-color:var(--md-sys-color-primary)!important;box-shadow:0 0 0 2px color-mix(in oklab,var(--md-sys-color-primary) 30%,transparent)}.row-empty-placeholder{flex:1;border:1px dashed var(--md-sys-color-outline-variant);margin:0;padding:16px;text-align:center;color:var(--md-sys-color-on-surface-variant);background:var(--md-sys-color-surface-container)}.row-placeholder-actions{margin-top:8px;display:flex;gap:8px;justify-content:center}\n"] }]
885
887
  }], propDecorators: { row: [{
886
888
  type: Input
887
889
  }], fieldMetadata: [{
@@ -1122,6 +1124,7 @@ class SectionConfiguratorComponent {
1122
1124
  selected = null;
1123
1125
  availableFieldsListId = 'available-fields-list';
1124
1126
  columnDropListIds = [];
1127
+ gapGlobal = 16;
1125
1128
  sectionChange = new EventEmitter();
1126
1129
  applyStyleToAll = new EventEmitter();
1127
1130
  remove = new EventEmitter();
@@ -1137,6 +1140,25 @@ class SectionConfiguratorComponent {
1137
1140
  }
1138
1141
  catch { }
1139
1142
  }
1143
+ // Gap below (local) controls
1144
+ onToggleGapCustomize(custom) {
1145
+ const next = { ...this.section };
1146
+ next.gapCustomized = custom;
1147
+ if (custom) {
1148
+ // Initialize with current global to provide immediate visual feedback
1149
+ next.gapBottom = this.section.gapBottom ?? this.gapGlobal;
1150
+ }
1151
+ else {
1152
+ // Revert to inherited: remove explicit gapBottom
1153
+ next.gapBottom = undefined;
1154
+ }
1155
+ this.sectionChange.emit(next);
1156
+ }
1157
+ onSectionGapChange(px) {
1158
+ const n = Number(px);
1159
+ const next = { ...this.section, gapCustomized: true, gapBottom: isFinite(n) ? n : 0 };
1160
+ this.sectionChange.emit(next);
1161
+ }
1140
1162
  // Emit only on blur to avoid focus loss during typing
1141
1163
  onTitleBlur() {
1142
1164
  this.onSectionUpdated();
@@ -1262,7 +1284,7 @@ class SectionConfiguratorComponent {
1262
1284
  this.applyStyleToAll.emit(patch);
1263
1285
  }
1264
1286
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: SectionConfiguratorComponent, deps: [{ token: i2$2.MatDialog }, { token: SectionPresetRegistry }], target: i0.ɵɵFactoryTarget.Component });
1265
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.4", type: SectionConfiguratorComponent, isStandalone: true, selector: "praxis-section-configurator", inputs: { section: "section", sectionIndex: "sectionIndex", allSections: "allSections", fieldMetadata: "fieldMetadata", selected: "selected", availableFieldsListId: "availableFieldsListId", columnDropListIds: "columnDropListIds" }, outputs: { sectionChange: "sectionChange", applyStyleToAll: "applyStyleToAll", remove: "remove", select: "select", fieldDrop: "fieldDrop" }, ngImport: i0, template: "<mat-card\n class=\"section-card\"\n cdkDrag\n (mouseenter)=\"onMouseEnter()\"\n (mouseleave)=\"onMouseLeave()\"\n [class.hovered]=\"isHovered\"\n [class.selected]=\"isThisSectionSelected()\"\n (click)=\"onSelectSection()\"\n tabindex=\"0\"\n role=\"button\"\n [attr.aria-label]=\"'Se\u00E7\u00E3o ' + (sectionIndex + 1)\"\n [attr.aria-selected]=\"isThisSectionSelected()\"\n>\n <mat-card-header class=\"section-header\">\n <mat-card-title class=\"title-wrapper\">\n <mat-form-field class=\"title-field\" appearance=\"outline\">\n <mat-label>T\u00EDtulo da Se\u00E7\u00E3o</mat-label>\n <mat-icon matPrefix>edit_note</mat-icon>\n <input\n matInput\n [(ngModel)]=\"section.title\"\n (blur)=\"onTitleBlur()\"\n />\n </mat-form-field>\n <button\n *ngIf=\"!section.description\"\n mat-icon-button\n class=\"add-desc-btn\"\n (click)=\"section.description = ''; onSectionUpdated()\"\n matTooltip=\"Adicionar descri\u00E7\u00E3o\"\n aria-label=\"Adicionar descri\u00E7\u00E3o\"\n >\n <mat-icon [praxisIcon]=\"'add'\"></mat-icon>\n </button>\n </mat-card-title>\n <button\n mat-icon-button\n [matMenuTriggerFor]=\"sectionMenu\"\n aria-label=\"Mais a\u00E7\u00F5es da se\u00E7\u00E3o\"\n matTooltip=\"Mais a\u00E7\u00F5es\"\n >\n <mat-icon [praxisIcon]=\"'more_vert'\"></mat-icon>\n </button>\n <mat-menu #sectionMenu=\"matMenu\">\n <button mat-menu-item (click)=\"openSectionPresets()\">\n <mat-icon [praxisIcon]=\"'view_quilt'\"></mat-icon>\n <span>Presets de se\u00E7\u00E3o\u2026</span>\n </button>\n <button mat-menu-item (click)=\"applyCurrentStyleToAll()\">\n <mat-icon [praxisIcon]=\"'format_paint'\"></mat-icon>\n <span>Aplicar estilo desta se\u00E7\u00E3o a todas</span>\n </button>\n <mat-divider></mat-divider>\n <button mat-menu-item *ngIf=\"section.description == null\" (click)=\"section.description = ''; onSectionUpdated()\">\n <mat-icon [praxisIcon]=\"'note_add'\"></mat-icon>\n <span>Adicionar descri\u00E7\u00E3o</span>\n </button>\n <button mat-menu-item *ngIf=\"section.description != null\" (click)=\"section.description = undefined; onSectionUpdated()\">\n <mat-icon [praxisIcon]=\"'backspace'\"></mat-icon>\n <span>Remover descri\u00E7\u00E3o</span>\n </button>\n <mat-divider></mat-divider>\n <button mat-menu-item (click)=\"onRemoveSection()\">\n <mat-icon [praxisIcon]=\"'delete'\"></mat-icon>\n <span>Remover se\u00E7\u00E3o</span>\n </button>\n </mat-menu>\n </mat-card-header>\n <mat-card-content>\n <mat-expansion-panel class=\"section-style\" hideToggle=\"false\">\n <mat-expansion-panel-header>\n <mat-panel-title>\n <mat-icon style=\"margin-right:6px\" aria-hidden=\"true\" [praxisIcon]=\"'format_paint'\"></mat-icon>\n Estilo da se\u00E7\u00E3o\n </mat-panel-title>\n <mat-panel-description>Tipografia e espa\u00E7amento</mat-panel-description>\n </mat-expansion-panel-header>\n\n <div class=\"typography-controls\" aria-label=\"Controle de tipografia e espa\u00E7amento\">\n <mat-form-field appearance=\"outline\" class=\"typo-field\">\n <mat-label>Fonte do t\u00EDtulo</mat-label>\n <mat-select [value]=\"section.titleStyle || 'titleMedium'\" (valueChange)=\"onTitleStyleChange($event)\">\n <mat-option value=\"titleLarge\">T\u00EDtulo grande</mat-option>\n <mat-option value=\"titleMedium\">T\u00EDtulo m\u00E9dio</mat-option>\n <mat-option value=\"titleSmall\">T\u00EDtulo pequeno</mat-option>\n <mat-option value=\"headlineSmall\">Headline</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"gap-field\">\n <mat-label>Gap do t\u00EDtulo (px)</mat-label>\n <input matInput type=\"number\" [(ngModel)]=\"section.titleGapBottom\" (blur)=\"onTitleBlur()\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"typo-field\">\n <mat-label>Fonte da descri\u00E7\u00E3o</mat-label>\n <mat-select [value]=\"section.descriptionStyle || 'bodyMedium'\" (valueChange)=\"onDescriptionStyleChange($event)\">\n <mat-option value=\"bodyLarge\">Corpo grande</mat-option>\n <mat-option value=\"bodyMedium\">Corpo m\u00E9dio</mat-option>\n <mat-option value=\"bodySmall\">Corpo pequeno</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"gap-field\">\n <mat-label>Gap da descri\u00E7\u00E3o (px)</mat-label>\n <input matInput type=\"number\" [(ngModel)]=\"section.descriptionGapBottom\" (blur)=\"onDescriptionBlur()\" />\n </mat-form-field>\n </div>\n </mat-expansion-panel>\n <mat-form-field\n *ngIf=\"section.description !== null && section.description !== undefined\"\n class=\"description-field full-width\"\n appearance=\"outline\"\n >\n <mat-label>Descri\u00E7\u00E3o da Se\u00E7\u00E3o</mat-label>\n <mat-icon matPrefix [praxisIcon]=\"'article'\"></mat-icon>\n <textarea\n matInput\n cdkTextareaAutosize\n cdkAutosizeMinRows=\"1\"\n cdkAutosizeMaxRows=\"5\"\n placeholder=\"Resumo curto do conte\u00FAdo da se\u00E7\u00E3o\"\n [(ngModel)]=\"section.description\"\n (blur)=\"onDescriptionBlur()\"\n ></textarea>\n <button mat-icon-button matSuffix type=\"button\" aria-label=\"Remover descri\u00E7\u00E3o\" (click)=\"section.description = undefined; onSectionUpdated()\">\n <mat-icon [praxisIcon]=\"'clear'\"></mat-icon>\n </button>\n </mat-form-field>\n\n <ng-container *ngIf=\"isThisSectionSelected(); else linhasTitle\">\n <div class=\"section-breadcrumbs\" (click)=\"$event.stopPropagation()\">\n <button\n type=\"button\"\n class=\"crumb as-button\"\n data-crumb=\"layout\"\n [attr.aria-label]=\"'Voltar ao Layout'\"\n disabled\n >\n Layout\n </button>\n <span class=\"sep\">\u203A</span>\n <button\n type=\"button\"\n class=\"crumb as-button crumb-section\"\n data-crumb=\"section\"\n (click)=\"onSelectSectionFromBreadcrumb($event)\"\n [attr.aria-label]=\"'Selecionar Se\u00E7\u00E3o ' + (sectionIndex + 1)\"\n >\n Se\u00E7\u00E3o {{ sectionIndex + 1 }}\n </button>\n <ng-container *ngIf=\"selected?.rowIndex != null\">\n <span class=\"sep\">\u203A</span>\n <button\n type=\"button\"\n class=\"crumb as-button crumb-row\"\n data-crumb=\"row\"\n (click)=\"onSelectRowFromBreadcrumb($event)\"\n [attr.aria-label]=\"'Selecionar Linha ' + (selected!.rowIndex! + 1)\"\n >\n Linha {{ selected!.rowIndex! + 1 }}\n </button>\n </ng-container>\n <ng-container *ngIf=\"selected?.columnIndex != null\">\n <span class=\"sep\">\u203A</span>\n <button\n type=\"button\"\n class=\"crumb as-button crumb-column\"\n data-crumb=\"column\"\n (click)=\"onSelectColumnFromBreadcrumb($event)\"\n [attr.aria-label]=\"'Selecionar Coluna ' + (selected!.columnIndex! + 1)\"\n >\n Coluna {{ selected!.columnIndex! + 1 }}\n </button>\n </ng-container>\n <ng-container *ngIf=\"selected?.fieldName\">\n <span class=\"sep\">\u203A</span>\n <span class=\"crumb active\">{{ selected!.fieldName }}</span>\n </ng-container>\n <button\n *ngIf=\"selected\"\n type=\"button\"\n class=\"crumb as-button crumb-clear\"\n data-crumb=\"clear\"\n (click)=\"onClearSelectionFromBreadcrumb($event)\"\n [attr.aria-label]=\"'Limpar sele\u00E7\u00E3o'\"\n >\n Limpar\n </button>\n </div>\n </ng-container>\n <ng-template #linhasTitle>\n <h5>Linhas</h5>\n </ng-template>\n <div\n class=\"row-list\"\n cdkDropList\n [cdkDropListData]=\"section.rows\"\n (cdkDropListDropped)=\"dropRow($event)\"\n >\n <praxis-row-configurator\n *ngFor=\"let row of section.rows; let i = index\"\n class=\"row-item\"\n [row]=\"row\"\n [fieldMetadata]=\"fieldMetadata\"\n [sectionIndex]=\"sectionIndex\"\n [rowIndex]=\"i\"\n [selected]=\"selected\"\n [availableFieldsListId]=\"availableFieldsListId\"\n [connectedDropListIds]=\"columnDropListIds\"\n (rowChange)=\"onRowUpdated(i, $event)\"\n (remove)=\"removeRow(i)\"\n (select)=\"select.emit($event)\"\n (fieldDrop)=\"onFieldDrop($event, i)\"\n cdkDrag\n ></praxis-row-configurator>\n </div>\n <div class=\"section-actions\" aria-label=\"A\u00E7\u00F5es da se\u00E7\u00E3o\">\n <button\n class=\"fab-add-row\"\n mat-fab\n color=\"primary\"\n (click)=\"addRow()\"\n matTooltip=\"Adicionar linha\"\n aria-label=\"Adicionar linha\"\n >\n <mat-icon>add</mat-icon>\n </button>\n </div>\n </mat-card-content>\n</mat-card>\n", styles: ["@charset \"UTF-8\";.section-card{background:var(--md-sys-color-surface, var(--sicoob-bg-elev-1));margin-bottom:16px;transition:border-color .2s ease;border:1px solid transparent}.section-card.hovered{border-color:var(--md-sys-color-primary, var(--sicoob-primary-default))}.section-card.selected{border-color:var(--md-sys-color-primary, var(--sicoob-primary-default));box-shadow:0 0 0 2px color-mix(in oklab,var(--md-sys-color-primary, var(--sicoob-primary-default)) 30%,transparent)}.section-breadcrumbs{font-size:12px;color:var(--md-sys-color-on-surface-variant, #7b8794);margin:4px 0 8px;display:flex;align-items:center;gap:6px}.section-breadcrumbs .as-button{background:transparent;border:none;padding:0 2px;color:inherit;font:inherit;cursor:pointer;border-radius:4px}.section-breadcrumbs .as-button:hover{color:var(--md-sys-color-primary, var(--sicoob-primary-default))}.section-breadcrumbs .crumb-clear{margin-left:6px;opacity:.85}.section-breadcrumbs .crumb.active{color:var(--md-sys-color-on-surface, #1f2937);font-weight:600}.section-breadcrumbs .sep{opacity:.6}.section-header{display:flex;justify-content:space-between;align-items:center;gap:12px}.title-wrapper{display:flex;align-items:center;gap:8px;width:100%}.add-desc-btn{margin-left:4px}.add-desc-btn.mat-mdc-icon-button{width:32px;height:32px;padding:0}.add-desc-btn .mat-mdc-button-touch-target{width:32px;height:32px}.add-desc-btn mat-icon{font-size:18px;width:18px;height:18px}.title-field{width:100%}:host ::ng-deep .title-field .mat-mdc-text-field-wrapper.mdc-text-field--outlined{height:36px;align-items:center}:host ::ng-deep .title-field .mat-mdc-form-field-infix{min-height:36px;padding-top:0!important;padding-bottom:0!important;display:flex;align-items:center}:host ::ng-deep .title-field .mat-mdc-form-field-subscript-wrapper{display:none}.section-subdesc{font-size:12px;color:var(--md-sys-color-on-surface-variant, #7b8794);margin-top:4px}.description-field{margin-top:0}.description-field textarea{padding:6px 8px;resize:none}:host ::ng-deep .description-field .mat-mdc-text-field-wrapper.mdc-text-field--outlined{min-height:36px;align-items:center}:host ::ng-deep .description-field .mat-mdc-form-field-infix{min-height:36px;padding-top:2px!important;padding-bottom:2px!important;display:flex;align-items:center}:host ::ng-deep .description-field .mat-mdc-form-field-subscript-wrapper{display:none}.description-field mat-label{font-size:.875rem}.add-row-button{margin-top:8px}.row-item{animation:fadeIn .3s ease}@keyframes fadeIn{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}.title-field.mat-focused mat-label{color:var(--md-sys-color-primary, var(--sicoob-primary-default));transition:color .3s}.section-card:hover{border-color:var(--md-sys-color-primary, var(--sicoob-primary-default))}:host ::ng-deep .section-card .mat-mdc-card-header{padding:8px 12px}:host ::ng-deep .section-card .mat-mdc-card-title{margin:0}:host ::ng-deep .section-card .mat-mdc-card-content{padding:0 12px 12px}.section-actions{position:relative;margin-top:12px;padding-top:16px;border-top:1px solid var(--md-sys-color-outline-variant, var(--sicoob-stroke-medium));min-height:28px}.section-style{margin:8px 0 12px}:host ::ng-deep .mat-expansion-panel{background:var(--md-sys-color-surface-container, var(--sicoob-bg-elev-2));border:1px solid var(--md-sys-color-outline-variant, var(--sicoob-stroke-medium));border-radius:12px}:host ::ng-deep .mat-expansion-panel-header{color:var(--md-sys-color-on-surface, var(--sicoob-text-high));background:var(--md-sys-color-surface-container, var(--sicoob-bg-elev-2))}:host ::ng-deep .mat-expansion-panel-header:hover{background:color-mix(in srgb,var(--md-sys-color-primary, var(--sicoob-primary-default)),transparent 90%)}:host ::ng-deep .mat-expansion-panel .mat-expansion-panel-body{background:var(--md-sys-color-surface, var(--sicoob-bg-elev-1));color:var(--md-sys-color-on-surface, var(--sicoob-text-high))}.typography-controls{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px}.typo-field,.gap-field{width:100%}.fab-add-row{position:absolute;top:-15px;left:50%;transform:translate(-50%,calc(-50% - var(--pfx-divider-w, 1px)));z-index:2;--pfx-fab-size: var(--pfx-fab-size-row, 32px);--pfx-fab-icon: var(--pfx-fab-icon-row, 18px);width:var(--pfx-fab-size);height:var(--pfx-fab-size);border-radius:50%}.fab-add-row.mat-mdc-fab{width:var(--pfx-fab-size);height:var(--pfx-fab-size);padding:0}.fab-add-row .mat-mdc-button-touch-target,.fab-add-row .mat-mdc-button-persistent-ripple,.fab-add-row .mat-mdc-button-ripple{width:var(--pfx-fab-size);height:var(--pfx-fab-size)}.fab-add-row mat-icon{font-size:var(--pfx-fab-icon);width:var(--pfx-fab-icon);height:var(--pfx-fab-icon)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i2$1.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i2$1.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "component", type: RowConfiguratorComponent, selector: "praxis-row-configurator", inputs: ["row", "fieldMetadata", "sectionIndex", "rowIndex", "selected", "availableFieldsListId", "connectedDropListIds"], outputs: ["rowChange", "remove", "fieldDrop", "select"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i6.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i7.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: "directive", type: i8$1.CdkTextareaAutosize, selector: "textarea[cdkTextareaAutosize]", inputs: ["cdkAutosizeMinRows", "cdkAutosizeMaxRows", "cdkTextareaAutosize", "placeholder"], exportAs: ["cdkTextareaAutosize"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i9.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: i9.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i3.MatFabButton, selector: "button[mat-fab], a[mat-fab], button[matFab], a[matFab]", inputs: ["extended"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.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: MatCardModule }, { kind: "component", type: i8.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i8.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i8.MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: i8.MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i5$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatDialogModule }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i6$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: i6$1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i6$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: TextFieldModule }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i15.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "component", type: i3$1.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i3$1.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i3$1.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "directive", type: i3$1.MatExpansionPanelDescription, selector: "mat-panel-description" }] });
1287
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.4", type: SectionConfiguratorComponent, isStandalone: true, selector: "praxis-section-configurator", inputs: { section: "section", sectionIndex: "sectionIndex", allSections: "allSections", fieldMetadata: "fieldMetadata", selected: "selected", availableFieldsListId: "availableFieldsListId", columnDropListIds: "columnDropListIds", gapGlobal: "gapGlobal" }, outputs: { sectionChange: "sectionChange", applyStyleToAll: "applyStyleToAll", remove: "remove", select: "select", fieldDrop: "fieldDrop" }, ngImport: i0, template: "<mat-card\n class=\"section-card\"\n cdkDrag\n (mouseenter)=\"onMouseEnter()\"\n (mouseleave)=\"onMouseLeave()\"\n [class.hovered]=\"isHovered\"\n [class.selected]=\"isThisSectionSelected()\"\n (click)=\"onSelectSection()\"\n tabindex=\"0\"\n role=\"button\"\n [attr.aria-label]=\"'Se\u00E7\u00E3o ' + (sectionIndex + 1)\"\n [attr.aria-selected]=\"isThisSectionSelected()\"\n>\n <mat-card-header class=\"section-header\">\n <mat-card-title class=\"title-wrapper\">\n <mat-form-field class=\"title-field\" appearance=\"outline\">\n <mat-label>T\u00EDtulo da Se\u00E7\u00E3o</mat-label>\n <mat-icon matPrefix>edit_note</mat-icon>\n <input\n matInput\n [(ngModel)]=\"section.title\"\n (blur)=\"onTitleBlur()\"\n />\n </mat-form-field>\n <button\n *ngIf=\"!section.description\"\n mat-icon-button\n class=\"add-desc-btn\"\n (click)=\"section.description = ''; onSectionUpdated()\"\n matTooltip=\"Adicionar descri\u00E7\u00E3o\"\n aria-label=\"Adicionar descri\u00E7\u00E3o\"\n >\n <mat-icon [praxisIcon]=\"'add'\"></mat-icon>\n </button>\n </mat-card-title>\n <button\n mat-icon-button\n [matMenuTriggerFor]=\"sectionMenu\"\n aria-label=\"Mais a\u00E7\u00F5es da se\u00E7\u00E3o\"\n matTooltip=\"Mais a\u00E7\u00F5es\"\n >\n <mat-icon [praxisIcon]=\"'more_vert'\"></mat-icon>\n </button>\n <mat-menu #sectionMenu=\"matMenu\">\n <button mat-menu-item (click)=\"openSectionPresets()\">\n <mat-icon [praxisIcon]=\"'view_quilt'\"></mat-icon>\n <span>Presets de se\u00E7\u00E3o\u2026</span>\n </button>\n <button mat-menu-item (click)=\"applyCurrentStyleToAll()\">\n <mat-icon [praxisIcon]=\"'format_paint'\"></mat-icon>\n <span>Aplicar estilo desta se\u00E7\u00E3o a todas</span>\n </button>\n <mat-divider></mat-divider>\n <button mat-menu-item *ngIf=\"section.description == null\" (click)=\"section.description = ''; onSectionUpdated()\">\n <mat-icon [praxisIcon]=\"'note_add'\"></mat-icon>\n <span>Adicionar descri\u00E7\u00E3o</span>\n </button>\n <button mat-menu-item *ngIf=\"section.description != null\" (click)=\"section.description = undefined; onSectionUpdated()\">\n <mat-icon [praxisIcon]=\"'backspace'\"></mat-icon>\n <span>Remover descri\u00E7\u00E3o</span>\n </button>\n <mat-divider></mat-divider>\n <button mat-menu-item (click)=\"onRemoveSection()\">\n <mat-icon [praxisIcon]=\"'delete'\"></mat-icon>\n <span>Remover se\u00E7\u00E3o</span>\n </button>\n </mat-menu>\n </mat-card-header>\n <mat-card-content>\n <mat-expansion-panel class=\"section-style\" hideToggle=\"false\">\n <mat-expansion-panel-header>\n <mat-panel-title>\n <mat-icon style=\"margin-right:6px\" aria-hidden=\"true\" [praxisIcon]=\"'format_paint'\"></mat-icon>\n Estilo da se\u00E7\u00E3o\n </mat-panel-title>\n <mat-panel-description>Tipografia e espa\u00E7amento</mat-panel-description>\n </mat-expansion-panel-header>\n\n <div class=\"typography-controls\" aria-label=\"Controle de tipografia e espa\u00E7amento\">\n <mat-form-field appearance=\"outline\" class=\"typo-field\">\n <mat-label>Fonte do t\u00EDtulo</mat-label>\n <mat-select [value]=\"section.titleStyle || 'titleMedium'\" (valueChange)=\"onTitleStyleChange($event)\">\n <mat-option value=\"titleLarge\">T\u00EDtulo grande</mat-option>\n <mat-option value=\"titleMedium\">T\u00EDtulo m\u00E9dio</mat-option>\n <mat-option value=\"titleSmall\">T\u00EDtulo pequeno</mat-option>\n <mat-option value=\"headlineSmall\">Headline</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"gap-field\">\n <mat-label>Gap do t\u00EDtulo (px)</mat-label>\n <input matInput type=\"number\" [(ngModel)]=\"section.titleGapBottom\" (blur)=\"onTitleBlur()\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"typo-field\">\n <mat-label>Fonte da descri\u00E7\u00E3o</mat-label>\n <mat-select [value]=\"section.descriptionStyle || 'bodyMedium'\" (valueChange)=\"onDescriptionStyleChange($event)\">\n <mat-option value=\"bodyLarge\">Corpo grande</mat-option>\n <mat-option value=\"bodyMedium\">Corpo m\u00E9dio</mat-option>\n <mat-option value=\"bodySmall\">Corpo pequeno</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"gap-field\">\n <mat-label>Gap da descri\u00E7\u00E3o (px)</mat-label>\n <input matInput type=\"number\" [(ngModel)]=\"section.descriptionGapBottom\" (blur)=\"onDescriptionBlur()\" />\n </mat-form-field>\n\n <!-- Gap abaixo da se\u00E7\u00E3o (herdado/personalizado) -->\n <div class=\"gap-row\">\n <mat-form-field appearance=\"outline\" class=\"gap-field\">\n <mat-label>Gap abaixo da se\u00E7\u00E3o (px)</mat-label>\n <input\n matInput\n type=\"number\"\n min=\"0\"\n step=\"4\"\n [ngModel]=\"section.gapCustomized ? (section.gapBottom ?? gapGlobal) : gapGlobal\"\n [disabled]=\"!section.gapCustomized\"\n (ngModelChange)=\"onSectionGapChange($event)\"\n />\n </mat-form-field>\n <span class=\"inherit-chip\" *ngIf=\"!section.gapCustomized\">\n Herdado ({{ gapGlobal }}px)\n </span>\n <mat-slide-toggle\n [ngModel]=\"section.gapCustomized === true\"\n (ngModelChange)=\"onToggleGapCustomize($event)\"\n labelPosition=\"after\"\n >\n Personalizar\n </mat-slide-toggle>\n </div>\n <div class=\"gap-helper\">Afeta o espa\u00E7amento externo entre esta se\u00E7\u00E3o e o pr\u00F3ximo bloco.</div>\n </div>\n </mat-expansion-panel>\n <mat-form-field\n *ngIf=\"section.description !== null && section.description !== undefined\"\n class=\"description-field full-width\"\n appearance=\"outline\"\n >\n <mat-label>Descri\u00E7\u00E3o da Se\u00E7\u00E3o</mat-label>\n <mat-icon matPrefix [praxisIcon]=\"'article'\"></mat-icon>\n <textarea\n matInput\n cdkTextareaAutosize\n cdkAutosizeMinRows=\"1\"\n cdkAutosizeMaxRows=\"5\"\n placeholder=\"Resumo curto do conte\u00FAdo da se\u00E7\u00E3o\"\n [(ngModel)]=\"section.description\"\n (blur)=\"onDescriptionBlur()\"\n ></textarea>\n <button mat-icon-button matSuffix type=\"button\" aria-label=\"Remover descri\u00E7\u00E3o\" (click)=\"section.description = undefined; onSectionUpdated()\">\n <mat-icon [praxisIcon]=\"'clear'\"></mat-icon>\n </button>\n </mat-form-field>\n\n <ng-container *ngIf=\"isThisSectionSelected(); else linhasTitle\">\n <div class=\"section-breadcrumbs\" (click)=\"$event.stopPropagation()\">\n <button\n type=\"button\"\n class=\"crumb as-button\"\n data-crumb=\"layout\"\n [attr.aria-label]=\"'Voltar ao Layout'\"\n disabled\n >\n Layout\n </button>\n <span class=\"sep\">\u203A</span>\n <button\n type=\"button\"\n class=\"crumb as-button crumb-section\"\n data-crumb=\"section\"\n (click)=\"onSelectSectionFromBreadcrumb($event)\"\n [attr.aria-label]=\"'Selecionar Se\u00E7\u00E3o ' + (sectionIndex + 1)\"\n >\n Se\u00E7\u00E3o {{ sectionIndex + 1 }}\n </button>\n <ng-container *ngIf=\"selected?.rowIndex != null\">\n <span class=\"sep\">\u203A</span>\n <button\n type=\"button\"\n class=\"crumb as-button crumb-row\"\n data-crumb=\"row\"\n (click)=\"onSelectRowFromBreadcrumb($event)\"\n [attr.aria-label]=\"'Selecionar Linha ' + (selected!.rowIndex! + 1)\"\n >\n Linha {{ selected!.rowIndex! + 1 }}\n </button>\n </ng-container>\n <ng-container *ngIf=\"selected?.columnIndex != null\">\n <span class=\"sep\">\u203A</span>\n <button\n type=\"button\"\n class=\"crumb as-button crumb-column\"\n data-crumb=\"column\"\n (click)=\"onSelectColumnFromBreadcrumb($event)\"\n [attr.aria-label]=\"'Selecionar Coluna ' + (selected!.columnIndex! + 1)\"\n >\n Coluna {{ selected!.columnIndex! + 1 }}\n </button>\n </ng-container>\n <ng-container *ngIf=\"selected?.fieldName\">\n <span class=\"sep\">\u203A</span>\n <span class=\"crumb active\">{{ selected!.fieldName }}</span>\n </ng-container>\n <button\n *ngIf=\"selected\"\n type=\"button\"\n class=\"crumb as-button crumb-clear\"\n data-crumb=\"clear\"\n (click)=\"onClearSelectionFromBreadcrumb($event)\"\n [attr.aria-label]=\"'Limpar sele\u00E7\u00E3o'\"\n >\n Limpar\n </button>\n </div>\n </ng-container>\n <ng-template #linhasTitle>\n <h5>Linhas</h5>\n </ng-template>\n <div\n class=\"row-list\"\n cdkDropList\n [cdkDropListData]=\"section.rows\"\n (cdkDropListDropped)=\"dropRow($event)\"\n >\n <praxis-row-configurator\n *ngFor=\"let row of section.rows; let i = index\"\n class=\"row-item\"\n [row]=\"row\"\n [fieldMetadata]=\"fieldMetadata\"\n [sectionIndex]=\"sectionIndex\"\n [rowIndex]=\"i\"\n [selected]=\"selected\"\n [availableFieldsListId]=\"availableFieldsListId\"\n [connectedDropListIds]=\"columnDropListIds\"\n (rowChange)=\"onRowUpdated(i, $event)\"\n (remove)=\"removeRow(i)\"\n (select)=\"select.emit($event)\"\n (fieldDrop)=\"onFieldDrop($event, i)\"\n cdkDrag\n ></praxis-row-configurator>\n </div>\n <div class=\"section-actions\" aria-label=\"A\u00E7\u00F5es da se\u00E7\u00E3o\">\n <button\n class=\"fab-add-row\"\n mat-fab\n color=\"primary\"\n (click)=\"addRow()\"\n matTooltip=\"Adicionar linha\"\n aria-label=\"Adicionar linha\"\n >\n <mat-icon>add</mat-icon>\n </button>\n </div>\n </mat-card-content>\n</mat-card>\n", styles: ["@charset \"UTF-8\";.section-card{background:var(--md-sys-color-surface, var(--sicoob-bg-elev-1));margin-bottom:16px;transition:border-color .2s ease;border:1px solid transparent}.section-card.hovered{border-color:var(--md-sys-color-primary, var(--sicoob-primary-default))}.section-card.selected{border-color:var(--md-sys-color-primary, var(--sicoob-primary-default));box-shadow:0 0 0 2px color-mix(in oklab,var(--md-sys-color-primary, var(--sicoob-primary-default)) 30%,transparent)}.section-card .mat-mdc-card-content{padding-bottom:var(--px-editor-section-gap, 16px)}.section-breadcrumbs{font-size:12px;color:var(--md-sys-color-on-surface-variant, #7b8794);margin:4px 0 8px;display:flex;align-items:center;gap:6px}.section-breadcrumbs .as-button{background:transparent;border:none;padding:0 2px;color:inherit;font:inherit;cursor:pointer;border-radius:4px}.section-breadcrumbs .as-button:hover{color:var(--md-sys-color-primary, var(--sicoob-primary-default))}.section-breadcrumbs .crumb-clear{margin-left:6px;opacity:.85}.section-breadcrumbs .crumb.active{color:var(--md-sys-color-on-surface, #1f2937);font-weight:600}.section-breadcrumbs .sep{opacity:.6}.section-header{display:flex;justify-content:space-between;align-items:center;gap:12px;min-height:56px}.title-wrapper{display:flex;align-items:center;gap:8px;width:100%}.add-desc-btn{margin-left:4px}.add-desc-btn.mat-mdc-icon-button{width:32px;height:32px;padding:0}.add-desc-btn .mat-mdc-button-touch-target{width:32px;height:32px}.add-desc-btn mat-icon{font-size:18px;width:18px;height:18px}.title-field{width:100%}:host ::ng-deep .title-field .mat-mdc-text-field-wrapper.mdc-text-field--outlined{height:36px;align-items:center}:host ::ng-deep .title-field .mat-mdc-form-field-infix{min-height:36px;padding-top:0!important;padding-bottom:0!important;display:flex;align-items:center}:host ::ng-deep .title-field .mat-mdc-form-field-subscript-wrapper{display:none}.section-subdesc{font-size:12px;color:var(--md-sys-color-on-surface-variant, #7b8794);margin-top:4px}.description-field{margin-top:0}.description-field textarea{padding:6px 8px;resize:none}:host ::ng-deep .description-field .mat-mdc-text-field-wrapper.mdc-text-field--outlined{min-height:36px;align-items:center}:host ::ng-deep .description-field .mat-mdc-form-field-infix{min-height:36px;padding-top:2px!important;padding-bottom:2px!important;display:flex;align-items:center}:host ::ng-deep .description-field .mat-mdc-form-field-subscript-wrapper{display:none}.description-field mat-label{font-size:.875rem}.add-row-button{margin-top:8px}.row-item{animation:fadeIn .3s ease}@keyframes fadeIn{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}.title-field.mat-focused mat-label{color:var(--md-sys-color-primary, var(--sicoob-primary-default));transition:color .3s}.section-card:hover{border-color:var(--md-sys-color-primary, var(--sicoob-primary-default))}:host ::ng-deep .section-card .mat-mdc-card-header{padding:8px 12px}:host ::ng-deep .section-card .mat-mdc-card-title{margin:0}:host ::ng-deep .section-card .mat-mdc-card-content{padding:0 12px 12px}.section-actions{position:relative;margin-top:12px;padding-top:16px;border-top:1px solid var(--md-sys-color-outline-variant, var(--sicoob-stroke-medium));min-height:28px}.section-style{margin:8px 0 12px}:host ::ng-deep .mat-expansion-panel{background:var(--md-sys-color-surface-container, var(--sicoob-bg-elev-2));border:1px solid var(--md-sys-color-outline-variant, var(--sicoob-stroke-medium));border-radius:12px}:host ::ng-deep .mat-expansion-panel-header{color:var(--md-sys-color-on-surface, var(--sicoob-text-high));background:var(--md-sys-color-surface-container, var(--sicoob-bg-elev-2))}:host ::ng-deep .mat-expansion-panel-header:hover{background:color-mix(in srgb,var(--md-sys-color-primary, var(--sicoob-primary-default)),transparent 90%)}:host ::ng-deep .mat-expansion-panel .mat-expansion-panel-body{background:var(--md-sys-color-surface, var(--sicoob-bg-elev-1));color:var(--md-sys-color-on-surface, var(--sicoob-text-high))}.section-style{margin:8px 0 var(--px-editor-section-gap, 16px)}.row-list{border-top:1px solid var(--px-editor-separator-color, color-mix(in srgb, var(--md-sys-color-outline) 60%, transparent));padding-top:12px;margin-top:8px}.gap-row{display:grid;grid-template-columns:220px auto auto;align-items:end;gap:12px}.gap-row .gap-field{width:100%}.inherit-chip{display:inline-block;padding:2px 8px;font-size:12px;border-radius:12px;border:1px dashed var(--md-sys-color-outline-variant);color:var(--md-sys-color-on-surface-variant);background:color-mix(in srgb,var(--md-sys-color-surface-variant) 15%,transparent);align-self:center}.gap-helper{grid-column:1/-1;font-size:12px;color:var(--md-sys-color-on-surface-variant);margin-top:-4px}.typography-controls{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px}.typo-field,.gap-field{width:100%}.fab-add-row{position:absolute;top:-15px;left:50%;transform:translate(-50%,calc(-50% - var(--pfx-divider-w, 1px)));z-index:2;--pfx-fab-size: var(--pfx-fab-size-row, 32px);--pfx-fab-icon: var(--pfx-fab-icon-row, 18px);width:var(--pfx-fab-size);height:var(--pfx-fab-size);border-radius:50%}.fab-add-row.mat-mdc-fab{width:var(--pfx-fab-size);height:var(--pfx-fab-size);padding:0}.fab-add-row .mat-mdc-button-touch-target,.fab-add-row .mat-mdc-button-persistent-ripple,.fab-add-row .mat-mdc-button-ripple{width:var(--pfx-fab-size);height:var(--pfx-fab-size)}.fab-add-row mat-icon{font-size:var(--pfx-fab-icon);width:var(--pfx-fab-icon);height:var(--pfx-fab-icon)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i2$1.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i2$1.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "component", type: RowConfiguratorComponent, selector: "praxis-row-configurator", inputs: ["row", "fieldMetadata", "sectionIndex", "rowIndex", "selected", "availableFieldsListId", "connectedDropListIds"], outputs: ["rowChange", "remove", "fieldDrop", "select"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i6.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i7.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: "directive", type: i8$1.CdkTextareaAutosize, selector: "textarea[cdkTextareaAutosize]", inputs: ["cdkAutosizeMinRows", "cdkAutosizeMaxRows", "cdkTextareaAutosize", "placeholder"], exportAs: ["cdkTextareaAutosize"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i9.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: i9.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i3.MatFabButton, selector: "button[mat-fab], a[mat-fab], button[matFab], a[matFab]", inputs: ["extended"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.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: MatCardModule }, { kind: "component", type: i8.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i8.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i8.MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: i8.MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i5$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatDialogModule }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i6$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: i6$1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i6$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: TextFieldModule }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i15.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "component", type: i3$1.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i3$1.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i3$1.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "directive", type: i3$1.MatExpansionPanelDescription, selector: "mat-panel-description" }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i6$2.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"] }] });
1266
1288
  }
1267
1289
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: SectionConfiguratorComponent, decorators: [{
1268
1290
  type: Component,
@@ -1284,7 +1306,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImpor
1284
1306
  TextFieldModule,
1285
1307
  MatDividerModule,
1286
1308
  MatExpansionModule,
1287
- ], template: "<mat-card\n class=\"section-card\"\n cdkDrag\n (mouseenter)=\"onMouseEnter()\"\n (mouseleave)=\"onMouseLeave()\"\n [class.hovered]=\"isHovered\"\n [class.selected]=\"isThisSectionSelected()\"\n (click)=\"onSelectSection()\"\n tabindex=\"0\"\n role=\"button\"\n [attr.aria-label]=\"'Se\u00E7\u00E3o ' + (sectionIndex + 1)\"\n [attr.aria-selected]=\"isThisSectionSelected()\"\n>\n <mat-card-header class=\"section-header\">\n <mat-card-title class=\"title-wrapper\">\n <mat-form-field class=\"title-field\" appearance=\"outline\">\n <mat-label>T\u00EDtulo da Se\u00E7\u00E3o</mat-label>\n <mat-icon matPrefix>edit_note</mat-icon>\n <input\n matInput\n [(ngModel)]=\"section.title\"\n (blur)=\"onTitleBlur()\"\n />\n </mat-form-field>\n <button\n *ngIf=\"!section.description\"\n mat-icon-button\n class=\"add-desc-btn\"\n (click)=\"section.description = ''; onSectionUpdated()\"\n matTooltip=\"Adicionar descri\u00E7\u00E3o\"\n aria-label=\"Adicionar descri\u00E7\u00E3o\"\n >\n <mat-icon [praxisIcon]=\"'add'\"></mat-icon>\n </button>\n </mat-card-title>\n <button\n mat-icon-button\n [matMenuTriggerFor]=\"sectionMenu\"\n aria-label=\"Mais a\u00E7\u00F5es da se\u00E7\u00E3o\"\n matTooltip=\"Mais a\u00E7\u00F5es\"\n >\n <mat-icon [praxisIcon]=\"'more_vert'\"></mat-icon>\n </button>\n <mat-menu #sectionMenu=\"matMenu\">\n <button mat-menu-item (click)=\"openSectionPresets()\">\n <mat-icon [praxisIcon]=\"'view_quilt'\"></mat-icon>\n <span>Presets de se\u00E7\u00E3o\u2026</span>\n </button>\n <button mat-menu-item (click)=\"applyCurrentStyleToAll()\">\n <mat-icon [praxisIcon]=\"'format_paint'\"></mat-icon>\n <span>Aplicar estilo desta se\u00E7\u00E3o a todas</span>\n </button>\n <mat-divider></mat-divider>\n <button mat-menu-item *ngIf=\"section.description == null\" (click)=\"section.description = ''; onSectionUpdated()\">\n <mat-icon [praxisIcon]=\"'note_add'\"></mat-icon>\n <span>Adicionar descri\u00E7\u00E3o</span>\n </button>\n <button mat-menu-item *ngIf=\"section.description != null\" (click)=\"section.description = undefined; onSectionUpdated()\">\n <mat-icon [praxisIcon]=\"'backspace'\"></mat-icon>\n <span>Remover descri\u00E7\u00E3o</span>\n </button>\n <mat-divider></mat-divider>\n <button mat-menu-item (click)=\"onRemoveSection()\">\n <mat-icon [praxisIcon]=\"'delete'\"></mat-icon>\n <span>Remover se\u00E7\u00E3o</span>\n </button>\n </mat-menu>\n </mat-card-header>\n <mat-card-content>\n <mat-expansion-panel class=\"section-style\" hideToggle=\"false\">\n <mat-expansion-panel-header>\n <mat-panel-title>\n <mat-icon style=\"margin-right:6px\" aria-hidden=\"true\" [praxisIcon]=\"'format_paint'\"></mat-icon>\n Estilo da se\u00E7\u00E3o\n </mat-panel-title>\n <mat-panel-description>Tipografia e espa\u00E7amento</mat-panel-description>\n </mat-expansion-panel-header>\n\n <div class=\"typography-controls\" aria-label=\"Controle de tipografia e espa\u00E7amento\">\n <mat-form-field appearance=\"outline\" class=\"typo-field\">\n <mat-label>Fonte do t\u00EDtulo</mat-label>\n <mat-select [value]=\"section.titleStyle || 'titleMedium'\" (valueChange)=\"onTitleStyleChange($event)\">\n <mat-option value=\"titleLarge\">T\u00EDtulo grande</mat-option>\n <mat-option value=\"titleMedium\">T\u00EDtulo m\u00E9dio</mat-option>\n <mat-option value=\"titleSmall\">T\u00EDtulo pequeno</mat-option>\n <mat-option value=\"headlineSmall\">Headline</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"gap-field\">\n <mat-label>Gap do t\u00EDtulo (px)</mat-label>\n <input matInput type=\"number\" [(ngModel)]=\"section.titleGapBottom\" (blur)=\"onTitleBlur()\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"typo-field\">\n <mat-label>Fonte da descri\u00E7\u00E3o</mat-label>\n <mat-select [value]=\"section.descriptionStyle || 'bodyMedium'\" (valueChange)=\"onDescriptionStyleChange($event)\">\n <mat-option value=\"bodyLarge\">Corpo grande</mat-option>\n <mat-option value=\"bodyMedium\">Corpo m\u00E9dio</mat-option>\n <mat-option value=\"bodySmall\">Corpo pequeno</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"gap-field\">\n <mat-label>Gap da descri\u00E7\u00E3o (px)</mat-label>\n <input matInput type=\"number\" [(ngModel)]=\"section.descriptionGapBottom\" (blur)=\"onDescriptionBlur()\" />\n </mat-form-field>\n </div>\n </mat-expansion-panel>\n <mat-form-field\n *ngIf=\"section.description !== null && section.description !== undefined\"\n class=\"description-field full-width\"\n appearance=\"outline\"\n >\n <mat-label>Descri\u00E7\u00E3o da Se\u00E7\u00E3o</mat-label>\n <mat-icon matPrefix [praxisIcon]=\"'article'\"></mat-icon>\n <textarea\n matInput\n cdkTextareaAutosize\n cdkAutosizeMinRows=\"1\"\n cdkAutosizeMaxRows=\"5\"\n placeholder=\"Resumo curto do conte\u00FAdo da se\u00E7\u00E3o\"\n [(ngModel)]=\"section.description\"\n (blur)=\"onDescriptionBlur()\"\n ></textarea>\n <button mat-icon-button matSuffix type=\"button\" aria-label=\"Remover descri\u00E7\u00E3o\" (click)=\"section.description = undefined; onSectionUpdated()\">\n <mat-icon [praxisIcon]=\"'clear'\"></mat-icon>\n </button>\n </mat-form-field>\n\n <ng-container *ngIf=\"isThisSectionSelected(); else linhasTitle\">\n <div class=\"section-breadcrumbs\" (click)=\"$event.stopPropagation()\">\n <button\n type=\"button\"\n class=\"crumb as-button\"\n data-crumb=\"layout\"\n [attr.aria-label]=\"'Voltar ao Layout'\"\n disabled\n >\n Layout\n </button>\n <span class=\"sep\">\u203A</span>\n <button\n type=\"button\"\n class=\"crumb as-button crumb-section\"\n data-crumb=\"section\"\n (click)=\"onSelectSectionFromBreadcrumb($event)\"\n [attr.aria-label]=\"'Selecionar Se\u00E7\u00E3o ' + (sectionIndex + 1)\"\n >\n Se\u00E7\u00E3o {{ sectionIndex + 1 }}\n </button>\n <ng-container *ngIf=\"selected?.rowIndex != null\">\n <span class=\"sep\">\u203A</span>\n <button\n type=\"button\"\n class=\"crumb as-button crumb-row\"\n data-crumb=\"row\"\n (click)=\"onSelectRowFromBreadcrumb($event)\"\n [attr.aria-label]=\"'Selecionar Linha ' + (selected!.rowIndex! + 1)\"\n >\n Linha {{ selected!.rowIndex! + 1 }}\n </button>\n </ng-container>\n <ng-container *ngIf=\"selected?.columnIndex != null\">\n <span class=\"sep\">\u203A</span>\n <button\n type=\"button\"\n class=\"crumb as-button crumb-column\"\n data-crumb=\"column\"\n (click)=\"onSelectColumnFromBreadcrumb($event)\"\n [attr.aria-label]=\"'Selecionar Coluna ' + (selected!.columnIndex! + 1)\"\n >\n Coluna {{ selected!.columnIndex! + 1 }}\n </button>\n </ng-container>\n <ng-container *ngIf=\"selected?.fieldName\">\n <span class=\"sep\">\u203A</span>\n <span class=\"crumb active\">{{ selected!.fieldName }}</span>\n </ng-container>\n <button\n *ngIf=\"selected\"\n type=\"button\"\n class=\"crumb as-button crumb-clear\"\n data-crumb=\"clear\"\n (click)=\"onClearSelectionFromBreadcrumb($event)\"\n [attr.aria-label]=\"'Limpar sele\u00E7\u00E3o'\"\n >\n Limpar\n </button>\n </div>\n </ng-container>\n <ng-template #linhasTitle>\n <h5>Linhas</h5>\n </ng-template>\n <div\n class=\"row-list\"\n cdkDropList\n [cdkDropListData]=\"section.rows\"\n (cdkDropListDropped)=\"dropRow($event)\"\n >\n <praxis-row-configurator\n *ngFor=\"let row of section.rows; let i = index\"\n class=\"row-item\"\n [row]=\"row\"\n [fieldMetadata]=\"fieldMetadata\"\n [sectionIndex]=\"sectionIndex\"\n [rowIndex]=\"i\"\n [selected]=\"selected\"\n [availableFieldsListId]=\"availableFieldsListId\"\n [connectedDropListIds]=\"columnDropListIds\"\n (rowChange)=\"onRowUpdated(i, $event)\"\n (remove)=\"removeRow(i)\"\n (select)=\"select.emit($event)\"\n (fieldDrop)=\"onFieldDrop($event, i)\"\n cdkDrag\n ></praxis-row-configurator>\n </div>\n <div class=\"section-actions\" aria-label=\"A\u00E7\u00F5es da se\u00E7\u00E3o\">\n <button\n class=\"fab-add-row\"\n mat-fab\n color=\"primary\"\n (click)=\"addRow()\"\n matTooltip=\"Adicionar linha\"\n aria-label=\"Adicionar linha\"\n >\n <mat-icon>add</mat-icon>\n </button>\n </div>\n </mat-card-content>\n</mat-card>\n", styles: ["@charset \"UTF-8\";.section-card{background:var(--md-sys-color-surface, var(--sicoob-bg-elev-1));margin-bottom:16px;transition:border-color .2s ease;border:1px solid transparent}.section-card.hovered{border-color:var(--md-sys-color-primary, var(--sicoob-primary-default))}.section-card.selected{border-color:var(--md-sys-color-primary, var(--sicoob-primary-default));box-shadow:0 0 0 2px color-mix(in oklab,var(--md-sys-color-primary, var(--sicoob-primary-default)) 30%,transparent)}.section-breadcrumbs{font-size:12px;color:var(--md-sys-color-on-surface-variant, #7b8794);margin:4px 0 8px;display:flex;align-items:center;gap:6px}.section-breadcrumbs .as-button{background:transparent;border:none;padding:0 2px;color:inherit;font:inherit;cursor:pointer;border-radius:4px}.section-breadcrumbs .as-button:hover{color:var(--md-sys-color-primary, var(--sicoob-primary-default))}.section-breadcrumbs .crumb-clear{margin-left:6px;opacity:.85}.section-breadcrumbs .crumb.active{color:var(--md-sys-color-on-surface, #1f2937);font-weight:600}.section-breadcrumbs .sep{opacity:.6}.section-header{display:flex;justify-content:space-between;align-items:center;gap:12px}.title-wrapper{display:flex;align-items:center;gap:8px;width:100%}.add-desc-btn{margin-left:4px}.add-desc-btn.mat-mdc-icon-button{width:32px;height:32px;padding:0}.add-desc-btn .mat-mdc-button-touch-target{width:32px;height:32px}.add-desc-btn mat-icon{font-size:18px;width:18px;height:18px}.title-field{width:100%}:host ::ng-deep .title-field .mat-mdc-text-field-wrapper.mdc-text-field--outlined{height:36px;align-items:center}:host ::ng-deep .title-field .mat-mdc-form-field-infix{min-height:36px;padding-top:0!important;padding-bottom:0!important;display:flex;align-items:center}:host ::ng-deep .title-field .mat-mdc-form-field-subscript-wrapper{display:none}.section-subdesc{font-size:12px;color:var(--md-sys-color-on-surface-variant, #7b8794);margin-top:4px}.description-field{margin-top:0}.description-field textarea{padding:6px 8px;resize:none}:host ::ng-deep .description-field .mat-mdc-text-field-wrapper.mdc-text-field--outlined{min-height:36px;align-items:center}:host ::ng-deep .description-field .mat-mdc-form-field-infix{min-height:36px;padding-top:2px!important;padding-bottom:2px!important;display:flex;align-items:center}:host ::ng-deep .description-field .mat-mdc-form-field-subscript-wrapper{display:none}.description-field mat-label{font-size:.875rem}.add-row-button{margin-top:8px}.row-item{animation:fadeIn .3s ease}@keyframes fadeIn{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}.title-field.mat-focused mat-label{color:var(--md-sys-color-primary, var(--sicoob-primary-default));transition:color .3s}.section-card:hover{border-color:var(--md-sys-color-primary, var(--sicoob-primary-default))}:host ::ng-deep .section-card .mat-mdc-card-header{padding:8px 12px}:host ::ng-deep .section-card .mat-mdc-card-title{margin:0}:host ::ng-deep .section-card .mat-mdc-card-content{padding:0 12px 12px}.section-actions{position:relative;margin-top:12px;padding-top:16px;border-top:1px solid var(--md-sys-color-outline-variant, var(--sicoob-stroke-medium));min-height:28px}.section-style{margin:8px 0 12px}:host ::ng-deep .mat-expansion-panel{background:var(--md-sys-color-surface-container, var(--sicoob-bg-elev-2));border:1px solid var(--md-sys-color-outline-variant, var(--sicoob-stroke-medium));border-radius:12px}:host ::ng-deep .mat-expansion-panel-header{color:var(--md-sys-color-on-surface, var(--sicoob-text-high));background:var(--md-sys-color-surface-container, var(--sicoob-bg-elev-2))}:host ::ng-deep .mat-expansion-panel-header:hover{background:color-mix(in srgb,var(--md-sys-color-primary, var(--sicoob-primary-default)),transparent 90%)}:host ::ng-deep .mat-expansion-panel .mat-expansion-panel-body{background:var(--md-sys-color-surface, var(--sicoob-bg-elev-1));color:var(--md-sys-color-on-surface, var(--sicoob-text-high))}.typography-controls{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px}.typo-field,.gap-field{width:100%}.fab-add-row{position:absolute;top:-15px;left:50%;transform:translate(-50%,calc(-50% - var(--pfx-divider-w, 1px)));z-index:2;--pfx-fab-size: var(--pfx-fab-size-row, 32px);--pfx-fab-icon: var(--pfx-fab-icon-row, 18px);width:var(--pfx-fab-size);height:var(--pfx-fab-size);border-radius:50%}.fab-add-row.mat-mdc-fab{width:var(--pfx-fab-size);height:var(--pfx-fab-size);padding:0}.fab-add-row .mat-mdc-button-touch-target,.fab-add-row .mat-mdc-button-persistent-ripple,.fab-add-row .mat-mdc-button-ripple{width:var(--pfx-fab-size);height:var(--pfx-fab-size)}.fab-add-row mat-icon{font-size:var(--pfx-fab-icon);width:var(--pfx-fab-icon);height:var(--pfx-fab-icon)}\n"] }]
1309
+ MatSlideToggleModule,
1310
+ ], template: "<mat-card\n class=\"section-card\"\n cdkDrag\n (mouseenter)=\"onMouseEnter()\"\n (mouseleave)=\"onMouseLeave()\"\n [class.hovered]=\"isHovered\"\n [class.selected]=\"isThisSectionSelected()\"\n (click)=\"onSelectSection()\"\n tabindex=\"0\"\n role=\"button\"\n [attr.aria-label]=\"'Se\u00E7\u00E3o ' + (sectionIndex + 1)\"\n [attr.aria-selected]=\"isThisSectionSelected()\"\n>\n <mat-card-header class=\"section-header\">\n <mat-card-title class=\"title-wrapper\">\n <mat-form-field class=\"title-field\" appearance=\"outline\">\n <mat-label>T\u00EDtulo da Se\u00E7\u00E3o</mat-label>\n <mat-icon matPrefix>edit_note</mat-icon>\n <input\n matInput\n [(ngModel)]=\"section.title\"\n (blur)=\"onTitleBlur()\"\n />\n </mat-form-field>\n <button\n *ngIf=\"!section.description\"\n mat-icon-button\n class=\"add-desc-btn\"\n (click)=\"section.description = ''; onSectionUpdated()\"\n matTooltip=\"Adicionar descri\u00E7\u00E3o\"\n aria-label=\"Adicionar descri\u00E7\u00E3o\"\n >\n <mat-icon [praxisIcon]=\"'add'\"></mat-icon>\n </button>\n </mat-card-title>\n <button\n mat-icon-button\n [matMenuTriggerFor]=\"sectionMenu\"\n aria-label=\"Mais a\u00E7\u00F5es da se\u00E7\u00E3o\"\n matTooltip=\"Mais a\u00E7\u00F5es\"\n >\n <mat-icon [praxisIcon]=\"'more_vert'\"></mat-icon>\n </button>\n <mat-menu #sectionMenu=\"matMenu\">\n <button mat-menu-item (click)=\"openSectionPresets()\">\n <mat-icon [praxisIcon]=\"'view_quilt'\"></mat-icon>\n <span>Presets de se\u00E7\u00E3o\u2026</span>\n </button>\n <button mat-menu-item (click)=\"applyCurrentStyleToAll()\">\n <mat-icon [praxisIcon]=\"'format_paint'\"></mat-icon>\n <span>Aplicar estilo desta se\u00E7\u00E3o a todas</span>\n </button>\n <mat-divider></mat-divider>\n <button mat-menu-item *ngIf=\"section.description == null\" (click)=\"section.description = ''; onSectionUpdated()\">\n <mat-icon [praxisIcon]=\"'note_add'\"></mat-icon>\n <span>Adicionar descri\u00E7\u00E3o</span>\n </button>\n <button mat-menu-item *ngIf=\"section.description != null\" (click)=\"section.description = undefined; onSectionUpdated()\">\n <mat-icon [praxisIcon]=\"'backspace'\"></mat-icon>\n <span>Remover descri\u00E7\u00E3o</span>\n </button>\n <mat-divider></mat-divider>\n <button mat-menu-item (click)=\"onRemoveSection()\">\n <mat-icon [praxisIcon]=\"'delete'\"></mat-icon>\n <span>Remover se\u00E7\u00E3o</span>\n </button>\n </mat-menu>\n </mat-card-header>\n <mat-card-content>\n <mat-expansion-panel class=\"section-style\" hideToggle=\"false\">\n <mat-expansion-panel-header>\n <mat-panel-title>\n <mat-icon style=\"margin-right:6px\" aria-hidden=\"true\" [praxisIcon]=\"'format_paint'\"></mat-icon>\n Estilo da se\u00E7\u00E3o\n </mat-panel-title>\n <mat-panel-description>Tipografia e espa\u00E7amento</mat-panel-description>\n </mat-expansion-panel-header>\n\n <div class=\"typography-controls\" aria-label=\"Controle de tipografia e espa\u00E7amento\">\n <mat-form-field appearance=\"outline\" class=\"typo-field\">\n <mat-label>Fonte do t\u00EDtulo</mat-label>\n <mat-select [value]=\"section.titleStyle || 'titleMedium'\" (valueChange)=\"onTitleStyleChange($event)\">\n <mat-option value=\"titleLarge\">T\u00EDtulo grande</mat-option>\n <mat-option value=\"titleMedium\">T\u00EDtulo m\u00E9dio</mat-option>\n <mat-option value=\"titleSmall\">T\u00EDtulo pequeno</mat-option>\n <mat-option value=\"headlineSmall\">Headline</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"gap-field\">\n <mat-label>Gap do t\u00EDtulo (px)</mat-label>\n <input matInput type=\"number\" [(ngModel)]=\"section.titleGapBottom\" (blur)=\"onTitleBlur()\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"typo-field\">\n <mat-label>Fonte da descri\u00E7\u00E3o</mat-label>\n <mat-select [value]=\"section.descriptionStyle || 'bodyMedium'\" (valueChange)=\"onDescriptionStyleChange($event)\">\n <mat-option value=\"bodyLarge\">Corpo grande</mat-option>\n <mat-option value=\"bodyMedium\">Corpo m\u00E9dio</mat-option>\n <mat-option value=\"bodySmall\">Corpo pequeno</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"gap-field\">\n <mat-label>Gap da descri\u00E7\u00E3o (px)</mat-label>\n <input matInput type=\"number\" [(ngModel)]=\"section.descriptionGapBottom\" (blur)=\"onDescriptionBlur()\" />\n </mat-form-field>\n\n <!-- Gap abaixo da se\u00E7\u00E3o (herdado/personalizado) -->\n <div class=\"gap-row\">\n <mat-form-field appearance=\"outline\" class=\"gap-field\">\n <mat-label>Gap abaixo da se\u00E7\u00E3o (px)</mat-label>\n <input\n matInput\n type=\"number\"\n min=\"0\"\n step=\"4\"\n [ngModel]=\"section.gapCustomized ? (section.gapBottom ?? gapGlobal) : gapGlobal\"\n [disabled]=\"!section.gapCustomized\"\n (ngModelChange)=\"onSectionGapChange($event)\"\n />\n </mat-form-field>\n <span class=\"inherit-chip\" *ngIf=\"!section.gapCustomized\">\n Herdado ({{ gapGlobal }}px)\n </span>\n <mat-slide-toggle\n [ngModel]=\"section.gapCustomized === true\"\n (ngModelChange)=\"onToggleGapCustomize($event)\"\n labelPosition=\"after\"\n >\n Personalizar\n </mat-slide-toggle>\n </div>\n <div class=\"gap-helper\">Afeta o espa\u00E7amento externo entre esta se\u00E7\u00E3o e o pr\u00F3ximo bloco.</div>\n </div>\n </mat-expansion-panel>\n <mat-form-field\n *ngIf=\"section.description !== null && section.description !== undefined\"\n class=\"description-field full-width\"\n appearance=\"outline\"\n >\n <mat-label>Descri\u00E7\u00E3o da Se\u00E7\u00E3o</mat-label>\n <mat-icon matPrefix [praxisIcon]=\"'article'\"></mat-icon>\n <textarea\n matInput\n cdkTextareaAutosize\n cdkAutosizeMinRows=\"1\"\n cdkAutosizeMaxRows=\"5\"\n placeholder=\"Resumo curto do conte\u00FAdo da se\u00E7\u00E3o\"\n [(ngModel)]=\"section.description\"\n (blur)=\"onDescriptionBlur()\"\n ></textarea>\n <button mat-icon-button matSuffix type=\"button\" aria-label=\"Remover descri\u00E7\u00E3o\" (click)=\"section.description = undefined; onSectionUpdated()\">\n <mat-icon [praxisIcon]=\"'clear'\"></mat-icon>\n </button>\n </mat-form-field>\n\n <ng-container *ngIf=\"isThisSectionSelected(); else linhasTitle\">\n <div class=\"section-breadcrumbs\" (click)=\"$event.stopPropagation()\">\n <button\n type=\"button\"\n class=\"crumb as-button\"\n data-crumb=\"layout\"\n [attr.aria-label]=\"'Voltar ao Layout'\"\n disabled\n >\n Layout\n </button>\n <span class=\"sep\">\u203A</span>\n <button\n type=\"button\"\n class=\"crumb as-button crumb-section\"\n data-crumb=\"section\"\n (click)=\"onSelectSectionFromBreadcrumb($event)\"\n [attr.aria-label]=\"'Selecionar Se\u00E7\u00E3o ' + (sectionIndex + 1)\"\n >\n Se\u00E7\u00E3o {{ sectionIndex + 1 }}\n </button>\n <ng-container *ngIf=\"selected?.rowIndex != null\">\n <span class=\"sep\">\u203A</span>\n <button\n type=\"button\"\n class=\"crumb as-button crumb-row\"\n data-crumb=\"row\"\n (click)=\"onSelectRowFromBreadcrumb($event)\"\n [attr.aria-label]=\"'Selecionar Linha ' + (selected!.rowIndex! + 1)\"\n >\n Linha {{ selected!.rowIndex! + 1 }}\n </button>\n </ng-container>\n <ng-container *ngIf=\"selected?.columnIndex != null\">\n <span class=\"sep\">\u203A</span>\n <button\n type=\"button\"\n class=\"crumb as-button crumb-column\"\n data-crumb=\"column\"\n (click)=\"onSelectColumnFromBreadcrumb($event)\"\n [attr.aria-label]=\"'Selecionar Coluna ' + (selected!.columnIndex! + 1)\"\n >\n Coluna {{ selected!.columnIndex! + 1 }}\n </button>\n </ng-container>\n <ng-container *ngIf=\"selected?.fieldName\">\n <span class=\"sep\">\u203A</span>\n <span class=\"crumb active\">{{ selected!.fieldName }}</span>\n </ng-container>\n <button\n *ngIf=\"selected\"\n type=\"button\"\n class=\"crumb as-button crumb-clear\"\n data-crumb=\"clear\"\n (click)=\"onClearSelectionFromBreadcrumb($event)\"\n [attr.aria-label]=\"'Limpar sele\u00E7\u00E3o'\"\n >\n Limpar\n </button>\n </div>\n </ng-container>\n <ng-template #linhasTitle>\n <h5>Linhas</h5>\n </ng-template>\n <div\n class=\"row-list\"\n cdkDropList\n [cdkDropListData]=\"section.rows\"\n (cdkDropListDropped)=\"dropRow($event)\"\n >\n <praxis-row-configurator\n *ngFor=\"let row of section.rows; let i = index\"\n class=\"row-item\"\n [row]=\"row\"\n [fieldMetadata]=\"fieldMetadata\"\n [sectionIndex]=\"sectionIndex\"\n [rowIndex]=\"i\"\n [selected]=\"selected\"\n [availableFieldsListId]=\"availableFieldsListId\"\n [connectedDropListIds]=\"columnDropListIds\"\n (rowChange)=\"onRowUpdated(i, $event)\"\n (remove)=\"removeRow(i)\"\n (select)=\"select.emit($event)\"\n (fieldDrop)=\"onFieldDrop($event, i)\"\n cdkDrag\n ></praxis-row-configurator>\n </div>\n <div class=\"section-actions\" aria-label=\"A\u00E7\u00F5es da se\u00E7\u00E3o\">\n <button\n class=\"fab-add-row\"\n mat-fab\n color=\"primary\"\n (click)=\"addRow()\"\n matTooltip=\"Adicionar linha\"\n aria-label=\"Adicionar linha\"\n >\n <mat-icon>add</mat-icon>\n </button>\n </div>\n </mat-card-content>\n</mat-card>\n", styles: ["@charset \"UTF-8\";.section-card{background:var(--md-sys-color-surface, var(--sicoob-bg-elev-1));margin-bottom:16px;transition:border-color .2s ease;border:1px solid transparent}.section-card.hovered{border-color:var(--md-sys-color-primary, var(--sicoob-primary-default))}.section-card.selected{border-color:var(--md-sys-color-primary, var(--sicoob-primary-default));box-shadow:0 0 0 2px color-mix(in oklab,var(--md-sys-color-primary, var(--sicoob-primary-default)) 30%,transparent)}.section-card .mat-mdc-card-content{padding-bottom:var(--px-editor-section-gap, 16px)}.section-breadcrumbs{font-size:12px;color:var(--md-sys-color-on-surface-variant, #7b8794);margin:4px 0 8px;display:flex;align-items:center;gap:6px}.section-breadcrumbs .as-button{background:transparent;border:none;padding:0 2px;color:inherit;font:inherit;cursor:pointer;border-radius:4px}.section-breadcrumbs .as-button:hover{color:var(--md-sys-color-primary, var(--sicoob-primary-default))}.section-breadcrumbs .crumb-clear{margin-left:6px;opacity:.85}.section-breadcrumbs .crumb.active{color:var(--md-sys-color-on-surface, #1f2937);font-weight:600}.section-breadcrumbs .sep{opacity:.6}.section-header{display:flex;justify-content:space-between;align-items:center;gap:12px;min-height:56px}.title-wrapper{display:flex;align-items:center;gap:8px;width:100%}.add-desc-btn{margin-left:4px}.add-desc-btn.mat-mdc-icon-button{width:32px;height:32px;padding:0}.add-desc-btn .mat-mdc-button-touch-target{width:32px;height:32px}.add-desc-btn mat-icon{font-size:18px;width:18px;height:18px}.title-field{width:100%}:host ::ng-deep .title-field .mat-mdc-text-field-wrapper.mdc-text-field--outlined{height:36px;align-items:center}:host ::ng-deep .title-field .mat-mdc-form-field-infix{min-height:36px;padding-top:0!important;padding-bottom:0!important;display:flex;align-items:center}:host ::ng-deep .title-field .mat-mdc-form-field-subscript-wrapper{display:none}.section-subdesc{font-size:12px;color:var(--md-sys-color-on-surface-variant, #7b8794);margin-top:4px}.description-field{margin-top:0}.description-field textarea{padding:6px 8px;resize:none}:host ::ng-deep .description-field .mat-mdc-text-field-wrapper.mdc-text-field--outlined{min-height:36px;align-items:center}:host ::ng-deep .description-field .mat-mdc-form-field-infix{min-height:36px;padding-top:2px!important;padding-bottom:2px!important;display:flex;align-items:center}:host ::ng-deep .description-field .mat-mdc-form-field-subscript-wrapper{display:none}.description-field mat-label{font-size:.875rem}.add-row-button{margin-top:8px}.row-item{animation:fadeIn .3s ease}@keyframes fadeIn{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}.title-field.mat-focused mat-label{color:var(--md-sys-color-primary, var(--sicoob-primary-default));transition:color .3s}.section-card:hover{border-color:var(--md-sys-color-primary, var(--sicoob-primary-default))}:host ::ng-deep .section-card .mat-mdc-card-header{padding:8px 12px}:host ::ng-deep .section-card .mat-mdc-card-title{margin:0}:host ::ng-deep .section-card .mat-mdc-card-content{padding:0 12px 12px}.section-actions{position:relative;margin-top:12px;padding-top:16px;border-top:1px solid var(--md-sys-color-outline-variant, var(--sicoob-stroke-medium));min-height:28px}.section-style{margin:8px 0 12px}:host ::ng-deep .mat-expansion-panel{background:var(--md-sys-color-surface-container, var(--sicoob-bg-elev-2));border:1px solid var(--md-sys-color-outline-variant, var(--sicoob-stroke-medium));border-radius:12px}:host ::ng-deep .mat-expansion-panel-header{color:var(--md-sys-color-on-surface, var(--sicoob-text-high));background:var(--md-sys-color-surface-container, var(--sicoob-bg-elev-2))}:host ::ng-deep .mat-expansion-panel-header:hover{background:color-mix(in srgb,var(--md-sys-color-primary, var(--sicoob-primary-default)),transparent 90%)}:host ::ng-deep .mat-expansion-panel .mat-expansion-panel-body{background:var(--md-sys-color-surface, var(--sicoob-bg-elev-1));color:var(--md-sys-color-on-surface, var(--sicoob-text-high))}.section-style{margin:8px 0 var(--px-editor-section-gap, 16px)}.row-list{border-top:1px solid var(--px-editor-separator-color, color-mix(in srgb, var(--md-sys-color-outline) 60%, transparent));padding-top:12px;margin-top:8px}.gap-row{display:grid;grid-template-columns:220px auto auto;align-items:end;gap:12px}.gap-row .gap-field{width:100%}.inherit-chip{display:inline-block;padding:2px 8px;font-size:12px;border-radius:12px;border:1px dashed var(--md-sys-color-outline-variant);color:var(--md-sys-color-on-surface-variant);background:color-mix(in srgb,var(--md-sys-color-surface-variant) 15%,transparent);align-self:center}.gap-helper{grid-column:1/-1;font-size:12px;color:var(--md-sys-color-on-surface-variant);margin-top:-4px}.typography-controls{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px}.typo-field,.gap-field{width:100%}.fab-add-row{position:absolute;top:-15px;left:50%;transform:translate(-50%,calc(-50% - var(--pfx-divider-w, 1px)));z-index:2;--pfx-fab-size: var(--pfx-fab-size-row, 32px);--pfx-fab-icon: var(--pfx-fab-icon-row, 18px);width:var(--pfx-fab-size);height:var(--pfx-fab-size);border-radius:50%}.fab-add-row.mat-mdc-fab{width:var(--pfx-fab-size);height:var(--pfx-fab-size);padding:0}.fab-add-row .mat-mdc-button-touch-target,.fab-add-row .mat-mdc-button-persistent-ripple,.fab-add-row .mat-mdc-button-ripple{width:var(--pfx-fab-size);height:var(--pfx-fab-size)}.fab-add-row mat-icon{font-size:var(--pfx-fab-icon);width:var(--pfx-fab-icon);height:var(--pfx-fab-icon)}\n"] }]
1288
1311
  }], ctorParameters: () => [{ type: i2$2.MatDialog }, { type: SectionPresetRegistry }], propDecorators: { section: [{
1289
1312
  type: Input
1290
1313
  }], sectionIndex: [{
@@ -1299,6 +1322,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImpor
1299
1322
  type: Input
1300
1323
  }], columnDropListIds: [{
1301
1324
  type: Input
1325
+ }], gapGlobal: [{
1326
+ type: Input
1302
1327
  }], sectionChange: [{
1303
1328
  type: Output
1304
1329
  }], applyStyleToAll: [{
@@ -1359,11 +1384,38 @@ class LayoutEditorComponent {
1359
1384
  prefs = inject(LayoutPrefsService);
1360
1385
  colorTokens = LayoutColorToken;
1361
1386
  selected = null;
1362
- // Bulk apply control for section gapBottom (px)
1363
- bulkSectionGapBottom = null;
1364
- applyGapBottomToAll() {
1365
- const px = this.bulkSectionGapBottom ?? 0;
1366
- const sections = this.config.sections.map((s) => ({ ...s, gapBottom: px }));
1387
+ // Global default for section gap (inherited when not customized)
1388
+ gapGlobal = 16;
1389
+ // Density control (global)
1390
+ density = 'cozy';
1391
+ get densityConfig() {
1392
+ switch (this.density) {
1393
+ case 'compact':
1394
+ return { gridGap: 8, sectionGap: 12 };
1395
+ case 'regular':
1396
+ return { gridGap: 16, sectionGap: 24 };
1397
+ case 'cozy':
1398
+ default:
1399
+ return { gridGap: 12, sectionGap: 16 };
1400
+ }
1401
+ }
1402
+ // Chrome toggles (border and divider)
1403
+ chromeToggles = ['border', 'divider'];
1404
+ get borderEnabled() { return this.chromeToggles.includes('border'); }
1405
+ get dividerEnabled() { return this.chromeToggles.includes('divider'); }
1406
+ canApplyAll() {
1407
+ if (!this.config?.sections?.length)
1408
+ return false;
1409
+ // Only enabled when there is at least one non-customized section
1410
+ return this.config.sections.some((s) => !s.gapCustomized);
1411
+ }
1412
+ applyGapToAll() {
1413
+ const px = this.gapGlobal ?? 0;
1414
+ const sections = this.config.sections.map((s) => {
1415
+ if (s.gapCustomized)
1416
+ return { ...s };
1417
+ return { ...s, gapBottom: px, gapCustomized: true };
1418
+ });
1367
1419
  this.emitNewConfig({ sections });
1368
1420
  }
1369
1421
  ngOnInit() {
@@ -1492,6 +1544,7 @@ class LayoutEditorComponent {
1492
1544
  id: `section_${Date.now()}`,
1493
1545
  title: 'Nova Seção',
1494
1546
  rows: [],
1547
+ gapCustomized: false,
1495
1548
  };
1496
1549
  const sections = [...this.config.sections, newSection];
1497
1550
  this.emitNewConfig({ sections });
@@ -1517,18 +1570,53 @@ class LayoutEditorComponent {
1517
1570
  const sections = this.config.sections.map((s) => ({ ...s, ...patch }));
1518
1571
  this.emitNewConfig({ sections });
1519
1572
  }
1573
+ // Keep section component instances stable to avoid collapsing expansion panels on small updates
1574
+ trackBySection(index, s) {
1575
+ return s.id ?? index;
1576
+ }
1520
1577
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: LayoutEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1521
1578
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.4", type: LayoutEditorComponent, isStandalone: true, selector: "praxis-layout-editor", inputs: { config: "config" }, outputs: { configChange: "configChange" }, host: { listeners: { "document:keydown": "handleKeydown($event)" } }, ngImport: i0, template: `
1522
- <div class="layout-editor-wrapper" cdkDropListGroup [class.no-available-fields]="!availableFields.length">
1523
- <div class="editor-toolbar" aria-label="Preferências do layout">
1524
- <mat-form-field appearance="outline" class="gap-control" matTooltip="Aplicar gap abaixo (px) em todas as seções">
1525
- <mat-label>Gap abaixo (todas) (px)</mat-label>
1526
- <input matInput type="number" min="0" [(ngModel)]="bulkSectionGapBottom" />
1579
+ <div class="layout-editor-wrapper"
1580
+ cdkDropListGroup
1581
+ [class.no-available-fields]="!availableFields.length"
1582
+ [style.--px-editor-section-gap.px]="densityConfig.sectionGap"
1583
+ [style.--pfx-grid-gap.px]="densityConfig.gridGap"
1584
+ [style.--pfx-form-stroke]="borderEnabled ? 'var(--md-sys-color-outline-variant)' : 'transparent'"
1585
+ [style.--px-editor-separator-color]="dividerEnabled ? 'color-mix(in srgb, var(--md-sys-color-outline) 60%, transparent)' : 'transparent'">
1586
+ <mat-toolbar class="editor-toolbar" aria-label="Preferências do layout">
1587
+ <span class="toolbar-title">Como organizar</span>
1588
+ <span class="spacer"></span>
1589
+ <mat-button-toggle-group [(ngModel)]="density" aria-label="Densidade" class="density-toggle">
1590
+ <mat-button-toggle value="compact" matTooltip="Compacta">
1591
+ <mat-icon>view_list</mat-icon>
1592
+ </mat-button-toggle>
1593
+ <mat-button-toggle value="cozy" matTooltip="Aconchegante">
1594
+ <mat-icon>view_stream</mat-icon>
1595
+ </mat-button-toggle>
1596
+ <mat-button-toggle value="regular" matTooltip="Regular">
1597
+ <mat-icon>view_comfy</mat-icon>
1598
+ </mat-button-toggle>
1599
+ </mat-button-toggle-group>
1600
+ <mat-button-toggle-group [(ngModel)]="chromeToggles" [multiple]="true" class="toggle-icons-group">
1601
+ <mat-button-toggle value="border" matTooltip="Borda da seção">
1602
+ <mat-icon>border_all</mat-icon>
1603
+ </mat-button-toggle>
1604
+ <mat-button-toggle value="divider" matTooltip="Separador estilo/grade">
1605
+ <mat-icon>horizontal_rule</mat-icon>
1606
+ </mat-button-toggle>
1607
+ </mat-button-toggle-group>
1608
+ <mat-form-field appearance="outline" class="gap-control" matTooltip="Define o padrão herdado por novas seções">
1609
+ <mat-label>Gap abaixo — Global</mat-label>
1610
+ <input matInput type="number" min="0" step="4" [(ngModel)]="gapGlobal" />
1611
+ <span matSuffix>px</span>
1527
1612
  </mat-form-field>
1528
- <button mat-stroked-button type="button" (click)="applyGapBottomToAll()" [disabled]="bulkSectionGapBottom == null">
1613
+ <button mat-stroked-button type="button"
1614
+ (click)="applyGapToAll()"
1615
+ [disabled]="!canApplyAll()"
1616
+ matTooltip="Sobrescreve seções que não estão personalizadas">
1529
1617
  Aplicar a todas
1530
1618
  </button>
1531
- </div>
1619
+ </mat-toolbar>
1532
1620
  <div
1533
1621
  class="available-fields"
1534
1622
  *ngIf="availableFields.length && !paletteCollapsed"
@@ -1581,12 +1669,13 @@ class LayoutEditorComponent {
1581
1669
  class="section-list"
1582
1670
  >
1583
1671
  <praxis-section-configurator
1584
- *ngFor="let section of config.sections; let i = index"
1672
+ *ngFor="let section of config.sections; let i = index; trackBy: trackBySection"
1585
1673
  [section]="section"
1586
1674
  [sectionIndex]="i"
1587
1675
  [allSections]="config.sections"
1588
1676
  [fieldMetadata]="config.fieldMetadata || []"
1589
1677
  [selected]="selected"
1678
+ [gapGlobal]="gapGlobal || 16"
1590
1679
  [availableFieldsListId]="
1591
1680
  availableFields.length ? 'available-fields-list' : null
1592
1681
  "
@@ -1613,7 +1702,7 @@ class LayoutEditorComponent {
1613
1702
  </div>
1614
1703
  </div>
1615
1704
  </div>
1616
- `, isInline: true, styles: [".layout-editor-wrapper{display:flex;flex-wrap:wrap;gap:16px}.layout-editor-wrapper.no-available-fields{gap:0}.editor-toolbar{display:flex;gap:8px;align-items:center;margin-bottom:8px;flex-basis:100%}.editor-toolbar .gap-control{width:140px}.available-fields{width:250px;border:1px solid var(--md-sys-color-outline-variant);padding:8px}.collapse-toggle{float:right}.no-fields-chip{position:absolute;top:8px;right:8px;padding:4px 8px;border:1px dashed var(--md-sys-color-outline);border-radius:16px;color:var(--md-sys-color-outline);font-size:12px;background:var(--md-sys-color-surface);pointer-events:none}.layout-canvas{flex-grow:1;overflow:visible;max-height:none;position:relative}.field-list{min-height:100px}.section-list{display:flex;flex-direction:column;gap:var(--pfx-section-gap, 20px)}.add-section-container{position:relative;padding-top:16px;margin-top:12px;border-top:1px solid var(--md-sys-color-outline-variant);min-height:28px}.fab-add-section{position:absolute;top:-30px;left:50%;transform:translate(-50%,calc(-50% - var(--pfx-divider-w, 1px)));z-index:2;--pfx-fab-size: var(--pfx-fab-size-section, 32px);--pfx-fab-icon: var(--pfx-fab-icon-section, 18px);width:var(--pfx-fab-size);height:var(--pfx-fab-size);border-radius:50%}.fab-add-section mat-icon{font-size:var(--pfx-fab-icon);width:var(--pfx-fab-icon);height:var(--pfx-fab-icon)}.fab-add-section.mat-mdc-fab{width:var(--pfx-fab-size);height:var(--pfx-fab-size);padding:0}.fab-add-section .mat-mdc-button-touch-target,.fab-add-section .mat-mdc-button-persistent-ripple,.fab-add-section .mat-mdc-button-ripple{width:var(--pfx-fab-size);height:var(--pfx-fab-size)}.cdk-drag-placeholder{opacity:.3;transition:opacity .2s ease}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i2$1.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i2$1.CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "directive", type: i2$1.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "ngmodule", type: ScrollingModule }, { kind: "component", type: SectionConfiguratorComponent, selector: "praxis-section-configurator", inputs: ["section", "sectionIndex", "allSections", "fieldMetadata", "selected", "availableFieldsListId", "columnDropListIds"], outputs: ["sectionChange", "applyStyleToAll", "remove", "select", "fieldDrop"] }, { kind: "component", type: FieldConfiguratorComponent, selector: "praxis-field-configurator", inputs: ["field"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.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: i3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i3.MatFabButton, selector: "button[mat-fab], a[mat-fab], button[matFab], a[matFab]", inputs: ["extended"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i5$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i7.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: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
1705
+ `, isInline: true, styles: [".layout-editor-wrapper{display:flex;flex-wrap:wrap;gap:16px}.layout-editor-wrapper.no-available-fields{gap:0}.editor-toolbar{position:sticky;top:0;z-index:3;display:flex;gap:12px;align-items:center;min-height:56px;background:var(--md-sys-color-surface-container, rgba(255, 255, 255, .02));border-bottom:1px solid var(--md-sys-color-outline-variant);box-shadow:var(--md-sys-elevation-level1, 0 1px 2px rgba(0, 0, 0, .2));padding:0 12px;margin:0 0 var(--px-editor-section-gap, 16px) 0}.editor-toolbar .toolbar-title{font:var(--mdc-typography-title-small, 600 14px/20px system-ui);color:var(--md-sys-color-on-surface);opacity:.9}.editor-toolbar .spacer{flex:1 1 auto}.editor-toolbar .gap-control{width:160px}.editor-toolbar .density-control{display:flex;align-items:center;gap:8px}.editor-toolbar .density-label{font:var(--mdc-typography-label-medium, 500 12px/16px system-ui);opacity:.9}.editor-toolbar .density-toggle .mat-button-toggle-button,.toggle-icons-group .mat-button-toggle-button{height:32px}.toggle-icons-group .mat-icon{font-size:20px;width:20px;height:20px;line-height:20px}.editor-toolbar .mat-mdc-form-field{margin:0!important;padding:0!important;align-self:center}.editor-toolbar .mat-mdc-text-field-wrapper{margin:0!important}.editor-toolbar input.mat-mdc-input-element{height:20px;line-height:20px;padding:0}.editor-toolbar :host ::ng-deep .mat-mdc-text-field-wrapper.mdc-text-field--outlined,.editor-toolbar :host ::ng-deep .mat-mdc-text-field-wrapper.mdc-text-field--filled{height:32px;align-items:center}.editor-toolbar :host ::ng-deep .mat-mdc-form-field-infix{min-height:32px;padding-top:0!important;padding-bottom:0!important;display:flex;flex-direction:row;align-items:center}.editor-toolbar :host ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none!important}.available-fields{width:250px;border:1px solid var(--md-sys-color-outline-variant);padding:8px}.collapse-toggle{float:right}.no-fields-chip{position:absolute;top:8px;right:8px;padding:4px 8px;border:1px dashed var(--md-sys-color-outline);border-radius:16px;color:var(--md-sys-color-outline);font-size:12px;background:var(--md-sys-color-surface);pointer-events:none}.layout-canvas{flex-grow:1;overflow:visible;max-height:none;position:relative}.field-list{min-height:100px}.section-list{display:flex;flex-direction:column;gap:var(--pfx-section-gap, 20px)}.add-section-container{position:relative;padding-top:16px;margin-top:12px;border-top:1px solid var(--md-sys-color-outline-variant);min-height:28px}.fab-add-section{position:absolute;top:-30px;left:50%;transform:translate(-50%,calc(-50% - var(--pfx-divider-w, 1px)));z-index:2;--pfx-fab-size: var(--pfx-fab-size-section, 32px);--pfx-fab-icon: var(--pfx-fab-icon-section, 18px);width:var(--pfx-fab-size);height:var(--pfx-fab-size);border-radius:50%}.fab-add-section mat-icon{font-size:var(--pfx-fab-icon);width:var(--pfx-fab-icon);height:var(--pfx-fab-icon)}.fab-add-section.mat-mdc-fab{width:var(--pfx-fab-size);height:var(--pfx-fab-size);padding:0}.fab-add-section .mat-mdc-button-touch-target,.fab-add-section .mat-mdc-button-persistent-ripple,.fab-add-section .mat-mdc-button-ripple{width:var(--pfx-fab-size);height:var(--pfx-fab-size)}.cdk-drag-placeholder{opacity:.3;transition:opacity .2s ease}:host ::ng-deep .mdc-text-field--filled{--mdc-filled-text-field-container-color: var(--md-sys-color-surface-container, #2a3038)}:host ::ng-deep .mdc-text-field__input::placeholder{color:var(--md-sys-color-on-surface-variant, #9aa7c7)!important;opacity:.95}:host ::ng-deep .mat-mdc-form-field-subscript-wrapper,:host ::ng-deep .mat-mdc-hint{color:var(--md-sys-color-on-surface-variant, #9aa7c7)!important}:host ::ng-deep .mdc-text-field--disabled .mdc-text-field__input,:host ::ng-deep .mat-mdc-select-disabled .mat-mdc-select-value{color:var(--md-sys-color-on-surface-variant, #9aa7c7)!important}:host ::ng-deep .mat-button-toggle-checked{background:var(--md-sys-color-primary-container, color-mix(in srgb, var(--md-sys-color-primary) 20%, var(--md-sys-color-surface) 80%))!important;color:var(--md-sys-color-on-primary-container, #e6eaf2)!important}:host{--px-editor-section-gap: 16px;--pfx-grid-gap: 12px;--pfx-section-gap: var(--px-editor-section-gap)}@media (min-width: 960px){:host{--px-editor-section-gap: 20px;--pfx-grid-gap: 16px}}@media (min-width: 1280px){:host{--px-editor-section-gap: 24px;--pfx-grid-gap: 20px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i2$1.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i2$1.CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "directive", type: i2$1.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "ngmodule", type: ScrollingModule }, { kind: "component", type: SectionConfiguratorComponent, selector: "praxis-section-configurator", inputs: ["section", "sectionIndex", "allSections", "fieldMetadata", "selected", "availableFieldsListId", "columnDropListIds", "gapGlobal"], outputs: ["sectionChange", "applyStyleToAll", "remove", "select", "fieldDrop"] }, { kind: "component", type: FieldConfiguratorComponent, selector: "praxis-field-configurator", inputs: ["field"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.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: i3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i3.MatFabButton, selector: "button[mat-fab], a[mat-fab], button[matFab], a[matFab]", inputs: ["extended"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i5$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i7.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: MatToolbarModule }, { kind: "component", type: i8$2.MatToolbar, selector: "mat-toolbar", inputs: ["color"], exportAs: ["matToolbar"] }, { kind: "ngmodule", type: MatButtonToggleModule }, { kind: "directive", type: i9$1.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled", "disabledInteractive", "hideSingleSelectionIndicator", "hideMultipleSelectionIndicator"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: i9$1.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: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
1617
1706
  }
1618
1707
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: LayoutEditorComponent, decorators: [{
1619
1708
  type: Component,
@@ -1628,18 +1717,51 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImpor
1628
1717
  MatTooltipModule,
1629
1718
  MatFormFieldModule,
1630
1719
  MatInputModule,
1720
+ MatToolbarModule,
1721
+ MatButtonToggleModule,
1631
1722
  FormsModule,
1632
1723
  ], template: `
1633
- <div class="layout-editor-wrapper" cdkDropListGroup [class.no-available-fields]="!availableFields.length">
1634
- <div class="editor-toolbar" aria-label="Preferências do layout">
1635
- <mat-form-field appearance="outline" class="gap-control" matTooltip="Aplicar gap abaixo (px) em todas as seções">
1636
- <mat-label>Gap abaixo (todas) (px)</mat-label>
1637
- <input matInput type="number" min="0" [(ngModel)]="bulkSectionGapBottom" />
1724
+ <div class="layout-editor-wrapper"
1725
+ cdkDropListGroup
1726
+ [class.no-available-fields]="!availableFields.length"
1727
+ [style.--px-editor-section-gap.px]="densityConfig.sectionGap"
1728
+ [style.--pfx-grid-gap.px]="densityConfig.gridGap"
1729
+ [style.--pfx-form-stroke]="borderEnabled ? 'var(--md-sys-color-outline-variant)' : 'transparent'"
1730
+ [style.--px-editor-separator-color]="dividerEnabled ? 'color-mix(in srgb, var(--md-sys-color-outline) 60%, transparent)' : 'transparent'">
1731
+ <mat-toolbar class="editor-toolbar" aria-label="Preferências do layout">
1732
+ <span class="toolbar-title">Como organizar</span>
1733
+ <span class="spacer"></span>
1734
+ <mat-button-toggle-group [(ngModel)]="density" aria-label="Densidade" class="density-toggle">
1735
+ <mat-button-toggle value="compact" matTooltip="Compacta">
1736
+ <mat-icon>view_list</mat-icon>
1737
+ </mat-button-toggle>
1738
+ <mat-button-toggle value="cozy" matTooltip="Aconchegante">
1739
+ <mat-icon>view_stream</mat-icon>
1740
+ </mat-button-toggle>
1741
+ <mat-button-toggle value="regular" matTooltip="Regular">
1742
+ <mat-icon>view_comfy</mat-icon>
1743
+ </mat-button-toggle>
1744
+ </mat-button-toggle-group>
1745
+ <mat-button-toggle-group [(ngModel)]="chromeToggles" [multiple]="true" class="toggle-icons-group">
1746
+ <mat-button-toggle value="border" matTooltip="Borda da seção">
1747
+ <mat-icon>border_all</mat-icon>
1748
+ </mat-button-toggle>
1749
+ <mat-button-toggle value="divider" matTooltip="Separador estilo/grade">
1750
+ <mat-icon>horizontal_rule</mat-icon>
1751
+ </mat-button-toggle>
1752
+ </mat-button-toggle-group>
1753
+ <mat-form-field appearance="outline" class="gap-control" matTooltip="Define o padrão herdado por novas seções">
1754
+ <mat-label>Gap abaixo — Global</mat-label>
1755
+ <input matInput type="number" min="0" step="4" [(ngModel)]="gapGlobal" />
1756
+ <span matSuffix>px</span>
1638
1757
  </mat-form-field>
1639
- <button mat-stroked-button type="button" (click)="applyGapBottomToAll()" [disabled]="bulkSectionGapBottom == null">
1758
+ <button mat-stroked-button type="button"
1759
+ (click)="applyGapToAll()"
1760
+ [disabled]="!canApplyAll()"
1761
+ matTooltip="Sobrescreve seções que não estão personalizadas">
1640
1762
  Aplicar a todas
1641
1763
  </button>
1642
- </div>
1764
+ </mat-toolbar>
1643
1765
  <div
1644
1766
  class="available-fields"
1645
1767
  *ngIf="availableFields.length && !paletteCollapsed"
@@ -1692,12 +1814,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImpor
1692
1814
  class="section-list"
1693
1815
  >
1694
1816
  <praxis-section-configurator
1695
- *ngFor="let section of config.sections; let i = index"
1817
+ *ngFor="let section of config.sections; let i = index; trackBy: trackBySection"
1696
1818
  [section]="section"
1697
1819
  [sectionIndex]="i"
1698
1820
  [allSections]="config.sections"
1699
1821
  [fieldMetadata]="config.fieldMetadata || []"
1700
1822
  [selected]="selected"
1823
+ [gapGlobal]="gapGlobal || 16"
1701
1824
  [availableFieldsListId]="
1702
1825
  availableFields.length ? 'available-fields-list' : null
1703
1826
  "
@@ -1724,7 +1847,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImpor
1724
1847
  </div>
1725
1848
  </div>
1726
1849
  </div>
1727
- `, styles: [".layout-editor-wrapper{display:flex;flex-wrap:wrap;gap:16px}.layout-editor-wrapper.no-available-fields{gap:0}.editor-toolbar{display:flex;gap:8px;align-items:center;margin-bottom:8px;flex-basis:100%}.editor-toolbar .gap-control{width:140px}.available-fields{width:250px;border:1px solid var(--md-sys-color-outline-variant);padding:8px}.collapse-toggle{float:right}.no-fields-chip{position:absolute;top:8px;right:8px;padding:4px 8px;border:1px dashed var(--md-sys-color-outline);border-radius:16px;color:var(--md-sys-color-outline);font-size:12px;background:var(--md-sys-color-surface);pointer-events:none}.layout-canvas{flex-grow:1;overflow:visible;max-height:none;position:relative}.field-list{min-height:100px}.section-list{display:flex;flex-direction:column;gap:var(--pfx-section-gap, 20px)}.add-section-container{position:relative;padding-top:16px;margin-top:12px;border-top:1px solid var(--md-sys-color-outline-variant);min-height:28px}.fab-add-section{position:absolute;top:-30px;left:50%;transform:translate(-50%,calc(-50% - var(--pfx-divider-w, 1px)));z-index:2;--pfx-fab-size: var(--pfx-fab-size-section, 32px);--pfx-fab-icon: var(--pfx-fab-icon-section, 18px);width:var(--pfx-fab-size);height:var(--pfx-fab-size);border-radius:50%}.fab-add-section mat-icon{font-size:var(--pfx-fab-icon);width:var(--pfx-fab-icon);height:var(--pfx-fab-icon)}.fab-add-section.mat-mdc-fab{width:var(--pfx-fab-size);height:var(--pfx-fab-size);padding:0}.fab-add-section .mat-mdc-button-touch-target,.fab-add-section .mat-mdc-button-persistent-ripple,.fab-add-section .mat-mdc-button-ripple{width:var(--pfx-fab-size);height:var(--pfx-fab-size)}.cdk-drag-placeholder{opacity:.3;transition:opacity .2s ease}\n"] }]
1850
+ `, styles: [".layout-editor-wrapper{display:flex;flex-wrap:wrap;gap:16px}.layout-editor-wrapper.no-available-fields{gap:0}.editor-toolbar{position:sticky;top:0;z-index:3;display:flex;gap:12px;align-items:center;min-height:56px;background:var(--md-sys-color-surface-container, rgba(255, 255, 255, .02));border-bottom:1px solid var(--md-sys-color-outline-variant);box-shadow:var(--md-sys-elevation-level1, 0 1px 2px rgba(0, 0, 0, .2));padding:0 12px;margin:0 0 var(--px-editor-section-gap, 16px) 0}.editor-toolbar .toolbar-title{font:var(--mdc-typography-title-small, 600 14px/20px system-ui);color:var(--md-sys-color-on-surface);opacity:.9}.editor-toolbar .spacer{flex:1 1 auto}.editor-toolbar .gap-control{width:160px}.editor-toolbar .density-control{display:flex;align-items:center;gap:8px}.editor-toolbar .density-label{font:var(--mdc-typography-label-medium, 500 12px/16px system-ui);opacity:.9}.editor-toolbar .density-toggle .mat-button-toggle-button,.toggle-icons-group .mat-button-toggle-button{height:32px}.toggle-icons-group .mat-icon{font-size:20px;width:20px;height:20px;line-height:20px}.editor-toolbar .mat-mdc-form-field{margin:0!important;padding:0!important;align-self:center}.editor-toolbar .mat-mdc-text-field-wrapper{margin:0!important}.editor-toolbar input.mat-mdc-input-element{height:20px;line-height:20px;padding:0}.editor-toolbar :host ::ng-deep .mat-mdc-text-field-wrapper.mdc-text-field--outlined,.editor-toolbar :host ::ng-deep .mat-mdc-text-field-wrapper.mdc-text-field--filled{height:32px;align-items:center}.editor-toolbar :host ::ng-deep .mat-mdc-form-field-infix{min-height:32px;padding-top:0!important;padding-bottom:0!important;display:flex;flex-direction:row;align-items:center}.editor-toolbar :host ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none!important}.available-fields{width:250px;border:1px solid var(--md-sys-color-outline-variant);padding:8px}.collapse-toggle{float:right}.no-fields-chip{position:absolute;top:8px;right:8px;padding:4px 8px;border:1px dashed var(--md-sys-color-outline);border-radius:16px;color:var(--md-sys-color-outline);font-size:12px;background:var(--md-sys-color-surface);pointer-events:none}.layout-canvas{flex-grow:1;overflow:visible;max-height:none;position:relative}.field-list{min-height:100px}.section-list{display:flex;flex-direction:column;gap:var(--pfx-section-gap, 20px)}.add-section-container{position:relative;padding-top:16px;margin-top:12px;border-top:1px solid var(--md-sys-color-outline-variant);min-height:28px}.fab-add-section{position:absolute;top:-30px;left:50%;transform:translate(-50%,calc(-50% - var(--pfx-divider-w, 1px)));z-index:2;--pfx-fab-size: var(--pfx-fab-size-section, 32px);--pfx-fab-icon: var(--pfx-fab-icon-section, 18px);width:var(--pfx-fab-size);height:var(--pfx-fab-size);border-radius:50%}.fab-add-section mat-icon{font-size:var(--pfx-fab-icon);width:var(--pfx-fab-icon);height:var(--pfx-fab-icon)}.fab-add-section.mat-mdc-fab{width:var(--pfx-fab-size);height:var(--pfx-fab-size);padding:0}.fab-add-section .mat-mdc-button-touch-target,.fab-add-section .mat-mdc-button-persistent-ripple,.fab-add-section .mat-mdc-button-ripple{width:var(--pfx-fab-size);height:var(--pfx-fab-size)}.cdk-drag-placeholder{opacity:.3;transition:opacity .2s ease}:host ::ng-deep .mdc-text-field--filled{--mdc-filled-text-field-container-color: var(--md-sys-color-surface-container, #2a3038)}:host ::ng-deep .mdc-text-field__input::placeholder{color:var(--md-sys-color-on-surface-variant, #9aa7c7)!important;opacity:.95}:host ::ng-deep .mat-mdc-form-field-subscript-wrapper,:host ::ng-deep .mat-mdc-hint{color:var(--md-sys-color-on-surface-variant, #9aa7c7)!important}:host ::ng-deep .mdc-text-field--disabled .mdc-text-field__input,:host ::ng-deep .mat-mdc-select-disabled .mat-mdc-select-value{color:var(--md-sys-color-on-surface-variant, #9aa7c7)!important}:host ::ng-deep .mat-button-toggle-checked{background:var(--md-sys-color-primary-container, color-mix(in srgb, var(--md-sys-color-primary) 20%, var(--md-sys-color-surface) 80%))!important;color:var(--md-sys-color-on-primary-container, #e6eaf2)!important}:host{--px-editor-section-gap: 16px;--pfx-grid-gap: 12px;--pfx-section-gap: var(--px-editor-section-gap)}@media (min-width: 960px){:host{--px-editor-section-gap: 20px;--pfx-grid-gap: 16px}}@media (min-width: 1280px){:host{--px-editor-section-gap: 24px;--pfx-grid-gap: 20px}}\n"] }]
1728
1851
  }], propDecorators: { config: [{
1729
1852
  type: Input
1730
1853
  }], configChange: [{
@@ -4249,7 +4372,7 @@ class PraxisDynamicFormConfigEditor {
4249
4372
  return copy;
4250
4373
  }
4251
4374
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: PraxisDynamicFormConfigEditor, deps: [{ token: CONFIG_STORAGE }, { token: FormConfigService }, { token: SETTINGS_PANEL_DATA, optional: true }], target: i0.ɵɵFactoryTarget.Component });
4252
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.4", type: PraxisDynamicFormConfigEditor, isStandalone: true, selector: "praxis-dynamic-form-config-editor", providers: [FormConfigService], viewQueries: [{ propertyName: "jsonEditor", first: true, predicate: JsonConfigEditorComponent, descendants: true }], ngImport: i0, template: " <mat-tab-group class=\"config-tabs\">\n <mat-tab label=\"Geral\">\n <div class=\"tab-content\">\n <mat-card>\n <mat-card-content>\n <div class=\"form-grid\">\n <div class=\"form-row\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>Modo do formul\u00E1rio (dados)</mat-label>\n <mat-select [(ngModel)]=\"inputMode\">\n <mat-option value=\"create\">create</mat-option>\n <mat-option value=\"edit\">edit</mat-option>\n <mat-option value=\"view\">view</mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n <p class=\"hint\">\n O <b>mode</b> controla o comportamento de dados (create/edit/view). J\u00E1 o <b>editModeEnabled</b> controla apenas a\n customiza\u00E7\u00E3o do layout (canvas) e \u00E9 independente do <b>mode</b>.\n </p>\n </div>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab label=\"Verifica\u00E7\u00E3o de Schema\">\n <div class=\"tab-content\">\n <mat-card>\n <mat-card-content>\n <div class=\"form-grid\">\n <div class=\"form-row\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>Notificar quando desatualizado</mat-label>\n <mat-select [(ngModel)]=\"schemaPrefs.notifyIfOutdated\">\n <mat-option value=\"both\">Banner + Snackbar</mat-option>\n <mat-option value=\"inline\">Somente Banner</mat-option>\n <mat-option value=\"snackbar\">Somente Snackbar</mat-option>\n <mat-option value=\"none\">Nenhum</mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n <div class=\"form-row\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>Soneca (ms)</mat-label>\n <input matInput type=\"number\" [(ngModel)]=\"schemaPrefs.snoozeMs\" />\n </mat-form-field>\n </div>\n <div class=\"form-row\">\n <mat-slide-toggle [(ngModel)]=\"schemaPrefs.autoOpenSettingsOnOutdated\">Abrir configura\u00E7\u00F5es automaticamente</mat-slide-toggle>\n </div>\n <div class=\"form-row\" *ngIf=\"serverMeta\">\n <div class=\"hint\">\n <div><b>Server Hash:</b> {{ serverMeta.serverHash || '\u2014' }}</div>\n <div><b>\u00DAltima verifica\u00E7\u00E3o:</b> {{ serverMeta.lastVerifiedAt || '\u2014' }}</div>\n </div>\n </div>\n </div>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab label=\"Layout\">\n <div class=\"tab-content\">\n <praxis-layout-editor\n [config]=\"editedConfig\"\n (configChange)=\"onConfigChange($event)\"\n ></praxis-layout-editor>\n </div>\n </mat-tab>\n <mat-tab label=\"Hooks\">\n <div class=\"tab-content\">\n <praxis-hooks-editor\n [config]=\"editedConfig\"\n (configChange)=\"onConfigChange($event)\"\n ></praxis-hooks-editor>\n </div>\n </mat-tab>\n <mat-tab *ngIf=\"isPresentationMode\" label=\"Modo Apresenta\u00E7\u00E3o\">\n <div class=\"tab-content\">\n <mat-card>\n <mat-card-content>\n <h3>Modo Apresenta\u00E7\u00E3o</h3>\n <p class=\"text-caption\">Configura\u00E7\u00F5es de exibi\u00E7\u00E3o aplicadas somente ao modo apresenta\u00E7\u00E3o.</p>\n\n <div class=\"presentation-layout\">\n <div class=\"presentation-controls\">\n <div class=\"control\">\n <label class=\"control__label\">Posi\u00E7\u00E3o do r\u00F3tulo</label>\n <mat-button-toggle-group\n [(ngModel)]=\"presentationPrefs.labelPosition\"\n aria-label=\"Posi\u00E7\u00E3o do r\u00F3tulo\"\n class=\"toggle-group\"\n >\n <mat-button-toggle value=\"above\">\n <mat-icon>view_stream</mat-icon>\n <span class=\"sr-only\">Acima</span>\n </mat-button-toggle>\n <mat-button-toggle value=\"left\">\n <mat-icon>view_column</mat-icon>\n <span class=\"sr-only\">\u00C0 esquerda</span>\n </mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n\n <div class=\"control\">\n <label class=\"control__label\">Densidade</label>\n <mat-button-toggle-group\n [(ngModel)]=\"presentationPrefs.density\"\n aria-label=\"Densidade\"\n class=\"toggle-group\"\n >\n <mat-button-toggle value=\"comfortable\">Confort\u00E1vel</mat-button-toggle>\n <mat-button-toggle value=\"cozy\">Intermedi\u00E1ria</mat-button-toggle>\n <mat-button-toggle value=\"compact\">Compacta</mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n\n <div class=\"control\">\n <label class=\"control__label\">Alinhamento do r\u00F3tulo</label>\n <mat-button-toggle-group\n [(ngModel)]=\"presentationPrefs.labelAlign\"\n aria-label=\"Alinhamento do r\u00F3tulo\"\n class=\"toggle-group\"\n >\n <mat-button-toggle value=\"start\"><mat-icon>format_align_left</mat-icon></mat-button-toggle>\n <mat-button-toggle value=\"center\"><mat-icon>format_align_center</mat-icon></mat-button-toggle>\n <mat-button-toggle value=\"end\"><mat-icon>format_align_right</mat-icon></mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n\n <div class=\"control\">\n <label class=\"control__label\">Alinhamento do valor</label>\n <mat-button-toggle-group\n [(ngModel)]=\"presentationPrefs.valueAlign\"\n aria-label=\"Alinhamento do valor\"\n class=\"toggle-group\"\n >\n <mat-button-toggle value=\"start\"><mat-icon>format_align_left</mat-icon></mat-button-toggle>\n <mat-button-toggle value=\"center\"><mat-icon>format_align_center</mat-icon></mat-button-toggle>\n <mat-button-toggle value=\"end\"><mat-icon>format_align_right</mat-icon></mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n\n <div class=\"control\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>Tamanho do r\u00F3tulo</mat-label>\n <input matInput type=\"number\" min=\"10\" [(ngModel)]=\"presentationPrefs.labelFontSize\" placeholder=\"ex.: 12\" />\n <span matSuffix>px</span>\n </mat-form-field>\n </div>\n\n <div class=\"control\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>Tamanho do valor</mat-label>\n <input matInput type=\"number\" min=\"10\" [(ngModel)]=\"presentationPrefs.valueFontSize\" placeholder=\"ex.: 16\" />\n <span matSuffix>px</span>\n </mat-form-field>\n </div>\n\n <div class=\"control\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>Largura do r\u00F3tulo (label \u00E0 esquerda)</mat-label>\n <input matInput type=\"number\" min=\"60\" [(ngModel)]=\"presentationPrefs.labelWidth\" placeholder=\"ex.: 140\" />\n <span matSuffix>px</span>\n </mat-form-field>\n </div>\n\n <div class=\"control control--inline\">\n <mat-slide-toggle [(ngModel)]=\"presentationPrefs.compact\">\n Modo compacto\n </mat-slide-toggle>\n <mat-checkbox [(ngModel)]=\"truncatePreview\">\n Truncar valores\n </mat-checkbox>\n </div>\n </div>\n\n <div class=\"presentation-preview\">\n <h4>Pr\u00E9\u2011visualiza\u00E7\u00E3o</h4>\n <div class=\"preview-card\">\n <div class=\"praxis-dynamic-form presentation-mode\"\n [ngClass]=\"{\n 'pres-compact': !!presentationPrefs.compact,\n 'pres-label-left': presentationPrefs.labelPosition === 'left',\n 'pres-label-above': presentationPrefs.labelPosition === 'above',\n 'pres-density-compact': presentationPrefs.density === 'compact',\n 'pres-density-cozy': presentationPrefs.density === 'cozy'\n }\"\n [style.--pfx-pres-label-size]=\"(presentationPrefs.labelFontSize || 12) + 'px'\"\n [style.--pfx-pres-value-size]=\"(presentationPrefs.valueFontSize || 16) + 'px'\"\n [style.--pfx-pres-label-width]=\"(presentationPrefs.labelWidth || 140) + 'px'\"\n [style.--pfx-pres-label-align]=\"presentationPrefs.labelAlign || 'start'\"\n [style.--pfx-pres-value-align]=\"presentationPrefs.valueAlign || 'start'\">\n <div class=\"preview-row\" *ngFor=\"let item of previewItems\">\n <span class=\"praxis-presentation__label\">{{ item.label }}</span>\n <span class=\"praxis-presentation__value\"\n [title]=\"truncatePreview ? item.value : null\"\n [style.maxWidth]=\"truncatePreview ? '280px' : null\"\n [style.overflow]=\"truncatePreview ? 'hidden' : null\"\n [style.textOverflow]=\"truncatePreview ? 'ellipsis' : null\"\n [style.whiteSpace]=\"truncatePreview ? 'nowrap' : 'normal'\">\n {{ item.value }}\n </span>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <p class=\"hint\">\n Estas configura\u00E7\u00F5es afetam apenas o Modo Apresenta\u00E7\u00E3o. S\u00E3o salvas por formul\u00E1rio\n e aplicadas no runtime atrav\u00E9s de vari\u00E1veis CSS e classes.\n </p>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab label=\"Comportamento\">\n <div class=\"tab-content\">\n <praxis-behavior-editor\n [config]=\"editedConfig\"\n (configChange)=\"onConfigChange($event)\"\n ></praxis-behavior-editor>\n </div>\n </mat-tab>\n <mat-tab label=\"A\u00E7\u00F5es\">\n <div class=\"tab-content\">\n <praxis-actions-editor\n [config]=\"editedConfig\"\n (configChange)=\"onConfigChange($event)\"\n ></praxis-actions-editor>\n </div>\n </mat-tab>\n <mat-tab label=\"Regras\">\n <div class=\"tab-content visual-builder-content\">\n <praxis-visual-builder\n [config]=\"ruleBuilderConfig\"\n [initialRules]=\"ruleBuilderState\"\n (rulesChanged)=\"onRulesChanged($event)\"\n ></praxis-visual-builder>\n </div>\n </mat-tab>\n <mat-tab label=\"Cascatas\">\n <div class=\"tab-content\">\n <praxis-cascade-manager-tab\n [fields]=\"editedConfig.fieldMetadata || []\"\n (apply)=\"onCascadeApply($event)\"\n ></praxis-cascade-manager-tab>\n </div>\n </mat-tab>\n <mat-tab label=\"Mensagens\">\n <div class=\"tab-content\">\n <praxis-messages-editor\n [config]=\"editedConfig\"\n (configChange)=\"onConfigChange($event)\"\n ></praxis-messages-editor>\n </div>\n </mat-tab>\n <mat-tab label=\"Navega\u00E7\u00E3o\">\n <div class=\"tab-content\">\n <mat-card>\n <mat-card-content>\n <p>\n Configure o comportamento do bot\u00E3o Voltar quando este formul\u00E1rio\n for aberto via CRUD (rota ou modal).\n </p>\n <div class=\"form-row\">\n <label for=\"returnTo\">Rota de retorno (returnTo)</label>\n <input\n id=\"returnTo\"\n type=\"text\"\n class=\"text-input\"\n [(ngModel)]=\"backConfig!.returnTo\"\n placeholder=\"/funcionarios\"\n />\n </div>\n <div class=\"form-row\">\n <label>\n <input\n type=\"checkbox\"\n [(ngModel)]=\"backConfig!.confirmOnDirty\"\n />\n Confirmar ao sair com altera\u00E7\u00F5es\n </label>\n </div>\n <p class=\"hint\">\n Observa\u00E7\u00E3o: estas configura\u00E7\u00F5es afetam o fluxo de navega\u00E7\u00E3o do\n CRUD e podem ser sobrepostas por metadados do recurso.\n </p>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab label=\"JSON\">\n <div class=\"tab-content\">\n <form-json-config-editor\n [config]=\"editedConfig\"\n (configChange)=\"onJsonConfigChange($event)\"\n (validationChange)=\"onJsonValidationChange($event)\"\n (editorEvent)=\"onJsonEditorEvent($event)\"\n >\n </form-json-config-editor>\n </div>\n </mat-tab>\n </mat-tab-group>\n", styles: ["@charset \"UTF-8\";.config-tabs{height:auto}.tab-content{padding:16px;height:auto;overflow:visible}.form-row{display:block;margin-bottom:12px}.w-100{width:100%}.visual-builder-content{padding:0;height:100%}.json-field{width:100%}.presentation-layout{display:flex;gap:16px;align-items:flex-start}.presentation-controls{flex:1 1 60%;display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:12px 16px}.control{display:flex;flex-direction:column}.control__label{font-size:12px;color:var(--md-sys-color-on-surface-variant, #8a8a8a);margin-bottom:6px}.toggle-group{width:100%}.control--inline{grid-column:1/-1;display:flex;gap:16px;align-items:center}.presentation-preview{flex:0 0 360px;position:sticky;top:12px}.preview-card{border:1px solid var(--md-sys-color-outline, rgba(255, 255, 255, .12));border-radius:8px;padding:12px;background:var(--md-sys-color-surface-container, #2a3038)}.preview-row{display:flex;gap:8px;padding:6px 0;border-bottom:1px dashed var(--md-sys-color-outline-variant, rgba(255, 255, 255, .08))}.preview-row:last-child{border-bottom:none}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.presentation-preview .praxis-presentation__label{color:var(--md-sys-color-on-surface-variant, #b9c0cf)}.presentation-preview .praxis-presentation__value{color:var(--md-sys-color-on-surface, #e6eaf2)}.presentation-preview .presentation-mode.pres-density-cozy .preview-row{padding:6px 0}.presentation-preview .presentation-mode.pres-density-compact .preview-row,.presentation-preview .presentation-mode.pres-compact .preview-row{padding:2px 0}.presentation-preview .presentation-mode.pres-label-left .preview-row{display:grid;grid-template-columns:var(--pfx-pres-label-width, 140px) 1fr;align-items:baseline;column-gap:10px}.presentation-preview .presentation-mode.pres-label-left .praxis-presentation__label{margin:0;text-align:var(--pfx-pres-label-align, start)}.presentation-preview .presentation-mode .praxis-presentation__value{text-align:var(--pfx-pres-value-align, start)}.presentation-preview h4{margin:0 0 8px;color:var(--md-sys-color-on-surface, #e6eaf2)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i6$3.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i6$3.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: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i8.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i8.MatCardContent, selector: "mat-card-content" }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i9.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: i9.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i7.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: MatCheckboxModule }, { kind: "component", type: i10.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i6$2.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: MatButtonToggleModule }, { kind: "directive", type: i12.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled", "disabledInteractive", "hideSingleSelectionIndicator", "hideMultipleSelectionIndicator"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: i12.MatButtonToggle, selector: "mat-button-toggle", inputs: ["aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "disableRipple", "appearance", "checked", "disabled", "disabledInteractive"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { kind: "component", type: JsonConfigEditorComponent, selector: "form-json-config-editor", inputs: ["config"], outputs: ["configChange", "validationChange", "editorEvent"] }, { kind: "component", type: LayoutEditorComponent, selector: "praxis-layout-editor", inputs: ["config"], outputs: ["configChange"] }, { kind: "component", type: BehaviorEditorComponent, selector: "praxis-behavior-editor", inputs: ["config"], outputs: ["configChange"] }, { kind: "component", type: ActionsEditorComponent$1, selector: "praxis-actions-editor", inputs: ["config"], outputs: ["configChange"] }, { kind: "component", type: MessagesEditorComponent, selector: "praxis-messages-editor", inputs: ["config"], outputs: ["configChange"] }, { kind: "component", type: HooksEditorComponent, selector: "praxis-hooks-editor", inputs: ["config"], outputs: ["configChange"] }, { kind: "component", type: PraxisVisualBuilder, selector: "praxis-visual-builder", inputs: ["config", "initialRules"], outputs: ["rulesChanged", "exportRequested", "importRequested"] }, { kind: "component", type: CascadeManagerTabComponent, selector: "praxis-cascade-manager-tab", inputs: ["fields", "connections"], outputs: ["apply", "cancel"] }] });
4375
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.4", type: PraxisDynamicFormConfigEditor, isStandalone: true, selector: "praxis-dynamic-form-config-editor", providers: [FormConfigService], viewQueries: [{ propertyName: "jsonEditor", first: true, predicate: JsonConfigEditorComponent, descendants: true }], ngImport: i0, template: " <mat-tab-group class=\"config-tabs\">\n <mat-tab label=\"Geral\">\n <div class=\"tab-content\">\n <mat-card>\n <mat-card-content>\n <div class=\"form-grid\">\n <div class=\"form-row\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>Modo do formul\u00E1rio (dados)</mat-label>\n <mat-select [(ngModel)]=\"inputMode\">\n <mat-option value=\"create\">create</mat-option>\n <mat-option value=\"edit\">edit</mat-option>\n <mat-option value=\"view\">view</mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n <p class=\"hint\">\n O <b>mode</b> controla o comportamento de dados (create/edit/view). J\u00E1 o <b>editModeEnabled</b> controla apenas a\n customiza\u00E7\u00E3o do layout (canvas) e \u00E9 independente do <b>mode</b>.\n </p>\n </div>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab label=\"Verifica\u00E7\u00E3o de Schema\">\n <div class=\"tab-content\">\n <mat-card>\n <mat-card-content>\n <div class=\"form-grid\">\n <div class=\"form-row\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>Notificar quando desatualizado</mat-label>\n <mat-select [(ngModel)]=\"schemaPrefs.notifyIfOutdated\">\n <mat-option value=\"both\">Banner + Snackbar</mat-option>\n <mat-option value=\"inline\">Somente Banner</mat-option>\n <mat-option value=\"snackbar\">Somente Snackbar</mat-option>\n <mat-option value=\"none\">Nenhum</mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n <div class=\"form-row\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>Soneca (ms)</mat-label>\n <input matInput type=\"number\" [(ngModel)]=\"schemaPrefs.snoozeMs\" />\n </mat-form-field>\n </div>\n <div class=\"form-row\">\n <mat-slide-toggle [(ngModel)]=\"schemaPrefs.autoOpenSettingsOnOutdated\">Abrir configura\u00E7\u00F5es automaticamente</mat-slide-toggle>\n </div>\n <div class=\"form-row\" *ngIf=\"serverMeta\">\n <div class=\"hint\">\n <div><b>Server Hash:</b> {{ serverMeta.serverHash || '\u2014' }}</div>\n <div><b>\u00DAltima verifica\u00E7\u00E3o:</b> {{ serverMeta.lastVerifiedAt || '\u2014' }}</div>\n </div>\n </div>\n </div>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab label=\"Layout\">\n <div class=\"tab-content\">\n <praxis-layout-editor\n [config]=\"editedConfig\"\n (configChange)=\"onConfigChange($event)\"\n ></praxis-layout-editor>\n </div>\n </mat-tab>\n <mat-tab label=\"Hooks\">\n <div class=\"tab-content\">\n <praxis-hooks-editor\n [config]=\"editedConfig\"\n (configChange)=\"onConfigChange($event)\"\n ></praxis-hooks-editor>\n </div>\n </mat-tab>\n <mat-tab *ngIf=\"isPresentationMode\" label=\"Modo Apresenta\u00E7\u00E3o\">\n <div class=\"tab-content\">\n <mat-card>\n <mat-card-content>\n <h3>Modo Apresenta\u00E7\u00E3o</h3>\n <p class=\"text-caption\">Configura\u00E7\u00F5es de exibi\u00E7\u00E3o aplicadas somente ao modo apresenta\u00E7\u00E3o.</p>\n\n <div class=\"presentation-layout\">\n <div class=\"presentation-controls\">\n <div class=\"control\">\n <label class=\"control__label\">Posi\u00E7\u00E3o do r\u00F3tulo</label>\n <mat-button-toggle-group\n [(ngModel)]=\"presentationPrefs.labelPosition\"\n aria-label=\"Posi\u00E7\u00E3o do r\u00F3tulo\"\n class=\"toggle-group\"\n >\n <mat-button-toggle value=\"above\">\n <mat-icon>view_stream</mat-icon>\n <span class=\"sr-only\">Acima</span>\n </mat-button-toggle>\n <mat-button-toggle value=\"left\">\n <mat-icon>view_column</mat-icon>\n <span class=\"sr-only\">\u00C0 esquerda</span>\n </mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n\n <div class=\"control\">\n <label class=\"control__label\">Densidade</label>\n <mat-button-toggle-group\n [(ngModel)]=\"presentationPrefs.density\"\n aria-label=\"Densidade\"\n class=\"toggle-group\"\n >\n <mat-button-toggle value=\"comfortable\">Confort\u00E1vel</mat-button-toggle>\n <mat-button-toggle value=\"cozy\">Intermedi\u00E1ria</mat-button-toggle>\n <mat-button-toggle value=\"compact\">Compacta</mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n\n <div class=\"control\">\n <label class=\"control__label\">Alinhamento do r\u00F3tulo</label>\n <mat-button-toggle-group\n [(ngModel)]=\"presentationPrefs.labelAlign\"\n aria-label=\"Alinhamento do r\u00F3tulo\"\n class=\"toggle-group\"\n >\n <mat-button-toggle value=\"start\"><mat-icon>format_align_left</mat-icon></mat-button-toggle>\n <mat-button-toggle value=\"center\"><mat-icon>format_align_center</mat-icon></mat-button-toggle>\n <mat-button-toggle value=\"end\"><mat-icon>format_align_right</mat-icon></mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n\n <div class=\"control\">\n <label class=\"control__label\">Alinhamento do valor</label>\n <mat-button-toggle-group\n [(ngModel)]=\"presentationPrefs.valueAlign\"\n aria-label=\"Alinhamento do valor\"\n class=\"toggle-group\"\n >\n <mat-button-toggle value=\"start\"><mat-icon>format_align_left</mat-icon></mat-button-toggle>\n <mat-button-toggle value=\"center\"><mat-icon>format_align_center</mat-icon></mat-button-toggle>\n <mat-button-toggle value=\"end\"><mat-icon>format_align_right</mat-icon></mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n\n <div class=\"control\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>Tamanho do r\u00F3tulo</mat-label>\n <input matInput type=\"number\" min=\"10\" [(ngModel)]=\"presentationPrefs.labelFontSize\" placeholder=\"ex.: 12\" />\n <span matSuffix>px</span>\n </mat-form-field>\n </div>\n\n <div class=\"control\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>Tamanho do valor</mat-label>\n <input matInput type=\"number\" min=\"10\" [(ngModel)]=\"presentationPrefs.valueFontSize\" placeholder=\"ex.: 16\" />\n <span matSuffix>px</span>\n </mat-form-field>\n </div>\n\n <div class=\"control\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>Largura do r\u00F3tulo (label \u00E0 esquerda)</mat-label>\n <input matInput type=\"number\" min=\"60\" [(ngModel)]=\"presentationPrefs.labelWidth\" placeholder=\"ex.: 140\" />\n <span matSuffix>px</span>\n </mat-form-field>\n </div>\n\n <div class=\"control control--inline\">\n <mat-slide-toggle [(ngModel)]=\"presentationPrefs.compact\">\n Modo compacto\n </mat-slide-toggle>\n <mat-checkbox [(ngModel)]=\"truncatePreview\">\n Truncar valores\n </mat-checkbox>\n </div>\n </div>\n\n <div class=\"presentation-preview\">\n <h4>Pr\u00E9\u2011visualiza\u00E7\u00E3o</h4>\n <div class=\"preview-card\">\n <div class=\"praxis-dynamic-form presentation-mode\"\n [ngClass]=\"{\n 'pres-compact': !!presentationPrefs.compact,\n 'pres-label-left': presentationPrefs.labelPosition === 'left',\n 'pres-label-above': presentationPrefs.labelPosition === 'above',\n 'pres-density-compact': presentationPrefs.density === 'compact',\n 'pres-density-cozy': presentationPrefs.density === 'cozy'\n }\"\n [style.--pfx-pres-label-size]=\"(presentationPrefs.labelFontSize || 12) + 'px'\"\n [style.--pfx-pres-value-size]=\"(presentationPrefs.valueFontSize || 16) + 'px'\"\n [style.--pfx-pres-label-width]=\"(presentationPrefs.labelWidth || 140) + 'px'\"\n [style.--pfx-pres-label-align]=\"presentationPrefs.labelAlign || 'start'\"\n [style.--pfx-pres-value-align]=\"presentationPrefs.valueAlign || 'start'\">\n <div class=\"preview-row\" *ngFor=\"let item of previewItems\">\n <span class=\"praxis-presentation__label\">{{ item.label }}</span>\n <span class=\"praxis-presentation__value\"\n [title]=\"truncatePreview ? item.value : null\"\n [style.maxWidth]=\"truncatePreview ? '280px' : null\"\n [style.overflow]=\"truncatePreview ? 'hidden' : null\"\n [style.textOverflow]=\"truncatePreview ? 'ellipsis' : null\"\n [style.whiteSpace]=\"truncatePreview ? 'nowrap' : 'normal'\">\n {{ item.value }}\n </span>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <p class=\"hint\">\n Estas configura\u00E7\u00F5es afetam apenas o Modo Apresenta\u00E7\u00E3o. S\u00E3o salvas por formul\u00E1rio\n e aplicadas no runtime atrav\u00E9s de vari\u00E1veis CSS e classes.\n </p>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab label=\"Comportamento\">\n <div class=\"tab-content\">\n <praxis-behavior-editor\n [config]=\"editedConfig\"\n (configChange)=\"onConfigChange($event)\"\n ></praxis-behavior-editor>\n </div>\n </mat-tab>\n <mat-tab label=\"A\u00E7\u00F5es\">\n <div class=\"tab-content\">\n <praxis-actions-editor\n [config]=\"editedConfig\"\n (configChange)=\"onConfigChange($event)\"\n ></praxis-actions-editor>\n </div>\n </mat-tab>\n <mat-tab label=\"Regras\">\n <div class=\"tab-content visual-builder-content\">\n <praxis-visual-builder\n [config]=\"ruleBuilderConfig\"\n [initialRules]=\"ruleBuilderState\"\n (rulesChanged)=\"onRulesChanged($event)\"\n ></praxis-visual-builder>\n </div>\n </mat-tab>\n <mat-tab label=\"Cascatas\">\n <div class=\"tab-content\">\n <praxis-cascade-manager-tab\n [fields]=\"editedConfig.fieldMetadata || []\"\n (apply)=\"onCascadeApply($event)\"\n ></praxis-cascade-manager-tab>\n </div>\n </mat-tab>\n <mat-tab label=\"Mensagens\">\n <div class=\"tab-content\">\n <praxis-messages-editor\n [config]=\"editedConfig\"\n (configChange)=\"onConfigChange($event)\"\n ></praxis-messages-editor>\n </div>\n </mat-tab>\n <mat-tab label=\"Navega\u00E7\u00E3o\">\n <div class=\"tab-content\">\n <mat-card>\n <mat-card-content>\n <p>\n Configure o comportamento do bot\u00E3o Voltar quando este formul\u00E1rio\n for aberto via CRUD (rota ou modal).\n </p>\n <div class=\"form-row\">\n <label for=\"returnTo\">Rota de retorno (returnTo)</label>\n <input\n id=\"returnTo\"\n type=\"text\"\n class=\"text-input\"\n [(ngModel)]=\"backConfig!.returnTo\"\n placeholder=\"/funcionarios\"\n />\n </div>\n <div class=\"form-row\">\n <label>\n <input\n type=\"checkbox\"\n [(ngModel)]=\"backConfig!.confirmOnDirty\"\n />\n Confirmar ao sair com altera\u00E7\u00F5es\n </label>\n </div>\n <p class=\"hint\">\n Observa\u00E7\u00E3o: estas configura\u00E7\u00F5es afetam o fluxo de navega\u00E7\u00E3o do\n CRUD e podem ser sobrepostas por metadados do recurso.\n </p>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab label=\"JSON\">\n <div class=\"tab-content\">\n <form-json-config-editor\n [config]=\"editedConfig\"\n (configChange)=\"onJsonConfigChange($event)\"\n (validationChange)=\"onJsonValidationChange($event)\"\n (editorEvent)=\"onJsonEditorEvent($event)\"\n >\n </form-json-config-editor>\n </div>\n </mat-tab>\n </mat-tab-group>\n", styles: ["@charset \"UTF-8\";.config-tabs{height:auto}.tab-content{padding:16px;height:auto;overflow:visible}.form-row{display:block;margin-bottom:12px}.w-100{width:100%}.visual-builder-content{padding:0;height:100%}.json-field{width:100%}.presentation-layout{display:flex;gap:16px;align-items:flex-start}.presentation-controls{flex:1 1 60%;display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:12px 16px}.control{display:flex;flex-direction:column}.control__label{font-size:12px;color:var(--md-sys-color-on-surface-variant, #8a8a8a);margin-bottom:6px}.toggle-group{width:100%}.control--inline{grid-column:1/-1;display:flex;gap:16px;align-items:center}.presentation-preview{flex:0 0 360px;position:sticky;top:12px}.preview-card{border:1px solid var(--md-sys-color-outline, rgba(255, 255, 255, .12));border-radius:8px;padding:12px;background:var(--md-sys-color-surface-container, #2a3038)}.preview-row{display:flex;gap:8px;padding:6px 0;border-bottom:1px dashed var(--md-sys-color-outline-variant, rgba(255, 255, 255, .08))}.preview-row:last-child{border-bottom:none}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.presentation-preview .praxis-presentation__label{color:var(--md-sys-color-on-surface-variant, #b9c0cf)}.presentation-preview .praxis-presentation__value{color:var(--md-sys-color-on-surface, #e6eaf2)}.presentation-preview .presentation-mode.pres-density-cozy .preview-row{padding:6px 0}.presentation-preview .presentation-mode.pres-density-compact .preview-row,.presentation-preview .presentation-mode.pres-compact .preview-row{padding:2px 0}.presentation-preview .presentation-mode.pres-label-left .preview-row{display:grid;grid-template-columns:var(--pfx-pres-label-width, 140px) 1fr;align-items:baseline;column-gap:10px}.presentation-preview .presentation-mode.pres-label-left .praxis-presentation__label{margin:0;text-align:var(--pfx-pres-label-align, start)}.presentation-preview .presentation-mode .praxis-presentation__value{text-align:var(--pfx-pres-value-align, start)}.presentation-preview h4{margin:0 0 8px;color:var(--md-sys-color-on-surface, #e6eaf2)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i6$3.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i6$3.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: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i8.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i8.MatCardContent, selector: "mat-card-content" }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i9.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: i9.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i7.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: MatCheckboxModule }, { kind: "component", type: i10.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i6$2.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: MatButtonToggleModule }, { kind: "directive", type: i9$1.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled", "disabledInteractive", "hideSingleSelectionIndicator", "hideMultipleSelectionIndicator"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: i9$1.MatButtonToggle, selector: "mat-button-toggle", inputs: ["aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "disableRipple", "appearance", "checked", "disabled", "disabledInteractive"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { kind: "component", type: JsonConfigEditorComponent, selector: "form-json-config-editor", inputs: ["config"], outputs: ["configChange", "validationChange", "editorEvent"] }, { kind: "component", type: LayoutEditorComponent, selector: "praxis-layout-editor", inputs: ["config"], outputs: ["configChange"] }, { kind: "component", type: BehaviorEditorComponent, selector: "praxis-behavior-editor", inputs: ["config"], outputs: ["configChange"] }, { kind: "component", type: ActionsEditorComponent$1, selector: "praxis-actions-editor", inputs: ["config"], outputs: ["configChange"] }, { kind: "component", type: MessagesEditorComponent, selector: "praxis-messages-editor", inputs: ["config"], outputs: ["configChange"] }, { kind: "component", type: HooksEditorComponent, selector: "praxis-hooks-editor", inputs: ["config"], outputs: ["configChange"] }, { kind: "component", type: PraxisVisualBuilder, selector: "praxis-visual-builder", inputs: ["config", "initialRules"], outputs: ["rulesChanged", "exportRequested", "importRequested"] }, { kind: "component", type: CascadeManagerTabComponent, selector: "praxis-cascade-manager-tab", inputs: ["fields", "connections"], outputs: ["apply", "cancel"] }] });
4253
4376
  }
4254
4377
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: PraxisDynamicFormConfigEditor, decorators: [{
4255
4378
  type: Component,
@@ -9932,7 +10055,7 @@ class PraxisDynamicForm {
9932
10055
  }
9933
10056
  catch { }
9934
10057
  }
9935
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: PraxisDynamicForm, deps: [{ token: i1$2.GenericCrudService }, { token: i1.FormBuilder }, { token: i0.ChangeDetectorRef }, { token: FormLayoutService }, { token: FormContextService }, { token: FormRulesService }, { token: i6$4.SettingsPanelService }, { token: i2$2.MatDialog }, { token: CONFIG_STORAGE }, { token: CONNECTION_STORAGE }, { token: i1$2.DynamicFormService }, { token: i8$2.MatSnackBar }, { token: CanvasStateService }, { token: DynamicFormLayoutService }, { token: i1$2.ErrorMessageService }, { token: i1$2.SchemaNormalizerService }, { token: i1$2.ComponentMetadataRegistry }, { token: i1$2.GlobalConfigService }, { token: i1$2.FormHooksRegistry, optional: true }, { token: FORM_HOOKS_PRESETS, optional: true }], target: i0.ɵɵFactoryTarget.Component });
10058
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: PraxisDynamicForm, deps: [{ token: i1$2.GenericCrudService }, { token: i1.FormBuilder }, { token: i0.ChangeDetectorRef }, { token: FormLayoutService }, { token: FormContextService }, { token: FormRulesService }, { token: i6$4.SettingsPanelService }, { token: i2$2.MatDialog }, { token: CONFIG_STORAGE }, { token: CONNECTION_STORAGE }, { token: i1$2.DynamicFormService }, { token: i8$3.MatSnackBar }, { token: CanvasStateService }, { token: DynamicFormLayoutService }, { token: i1$2.ErrorMessageService }, { token: i1$2.SchemaNormalizerService }, { token: i1$2.ComponentMetadataRegistry }, { token: i1$2.GlobalConfigService }, { token: i1$2.FormHooksRegistry, optional: true }, { token: FORM_HOOKS_PRESETS, optional: true }], target: i0.ɵɵFactoryTarget.Component });
9936
10059
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.4", type: PraxisDynamicForm, isStandalone: true, selector: "praxis-dynamic-form", inputs: { resourcePath: "resourcePath", resourceId: "resourceId", mode: "mode", config: "config", schemaSource: "schemaSource", editModeEnabled: "editModeEnabled", formId: "formId", layout: "layout", backConfig: "backConfig", hooks: "hooks", removeEmptyContainersOnSave: "removeEmptyContainersOnSave", reactiveValidation: "reactiveValidation", reactiveValidationDebounceMs: "reactiveValidationDebounceMs", notifyIfOutdated: "notifyIfOutdated", snoozeMs: "snoozeMs", autoOpenSettingsOnOutdated: "autoOpenSettingsOnOutdated", readonlyModeGlobal: "readonlyModeGlobal", disabledModeGlobal: "disabledModeGlobal", presentationModeGlobal: "presentationModeGlobal", visibleGlobal: "visibleGlobal", customEndpoints: "customEndpoints" }, outputs: { formSubmit: "formSubmit", formCancel: "formCancel", formReset: "formReset", configChange: "configChange", formReady: "formReady", valueChange: "valueChange", syncCompleted: "syncCompleted", initializationError: "initializationError", editModeEnabledChange: "editModeEnabledChange", customAction: "customAction", actionConfirmation: "actionConfirmation", schemaStatusChange: "schemaStatusChange" }, viewQueries: [{ propertyName: "formHost", first: true, predicate: ["formHost"], descendants: true }, { propertyName: "fieldLoaders", predicate: DynamicFieldLoaderDirective, descendants: true }], usesOnChanges: true, ngImport: i0, template: "@if (isLoading) {\n<!-- Loading State -->\n<div class=\"form-loading\">\n <mat-progress-spinner diameter=\"40\"></mat-progress-spinner>\n <p>Carregando formul\u00E1rio...</p>\n</div>\n} @else if (initializationStatus === 'error') {\n<!-- Error State -->\n<div class=\"form-error\">\n <mat-icon color=\"warn\" [praxisIcon]=\"'error'\"></mat-icon>\n <h3>{{ getErrorTitle() }}</h3>\n <p>{{ currentErrorMessage }}</p>\n @if (isRecoverable) {\n <button mat-stroked-button (click)=\"retryInitialization()\">\n <mat-icon [praxisIcon]=\"'refresh'\"></mat-icon>\n Tentar Novamente\n </button>\n }\n <button mat-button (click)=\"showDetailedError()\" class=\"show-details\">\n Ver Detalhes T\u00E9cnicos\n </button>\n <!-- Permitir corre\u00E7\u00E3o do resourcePath diretamente do estado de erro -->\n <button mat-flat-button color=\"primary\" (click)=\"openQuickConnect()\" class=\"connect-action\">\n <mat-icon [praxisIcon]=\"'bolt'\"></mat-icon>\n Conectar a recurso\n </button>\n</div>\n} @else if (initializationStatus === 'success') {\n<!-- Inline banner for schema change (only in edit mode) -->\n@if (shouldShowOutdatedInline()) {\n<div class=\"pfx-form-info-banner\" role=\"status\" aria-live=\"polite\">\n <div class=\"text\">O schema do servidor mudou. Reconciliar agora?</div>\n <div class=\"actions\">\n <button mat-stroked-button color=\"primary\" (click)=\"openConfigEditor()\">\n <mat-icon [praxisIcon]=\"'sync'\"></mat-icon>\n Reconciliar\n </button>\n <button mat-button (click)=\"onSnoozeOutdated()\">Lembrar depois</button>\n <button mat-button (click)=\"onIgnoreOutdated()\">Ignorar</button>\n </div>\n </div>\n}\n\n<!-- Configuration Controls -->\n@if (shouldShowConfigControls && editModeEnabled) {\n<div class=\"form-config-controls\">\n <button\n type=\"button\"\n mat-icon-button\n (click)=\"openConfigEditor()\"\n [disabled]=\"isLoading\"\n class=\"config-button\"\n [matBadge]=\"schemaOutdated ? '!' : ''\"\n [matBadgeHidden]=\"!schemaOutdated\"\n matBadgeColor=\"warn\" matBadgeSize=\"small\" matBadgePosition=\"above after\"\n [matTooltip]=\"schemaOutdated ? 'Schema do servidor mudou \u2014 Reconciliar' : 'Configurar formul\u00E1rio'\"\n >\n <mat-icon [praxisIcon]=\"'settings'\"></mat-icon>\n </button>\n <button\n type=\"button\"\n mat-icon-button\n (click)=\"disconnect()\"\n matTooltip=\"Desconectar da fonte de dados\"\n [disabled]=\"isLoading\"\n >\n <mat-icon [praxisIcon]=\"'link_off'\"></mat-icon>\n </button>\n</div>\n} }\n\n<!-- Form Content -->\n@if (!resourcePath && (!config.sections || config.sections.length === 0)) {\n <praxis-empty-state-card\n icon=\"link\"\n [title]=\"'Conecte o formul\u00E1rio \u00E0 fonte de dados'\"\n [description]=\"'Informe a rota do recurso da API para gerar automaticamente os campos do formul\u00E1rio.'\"\n [primaryAction]=\"{ label: 'Conectar \u00E0 fonte de dados', icon: 'bolt', action: openQuickConnect.bind(this) }\"\n ></praxis-empty-state-card>\n}\n<form\n #formHost\n (ngSubmit)=\"onSubmit()\"\n [attr.aria-busy]=\"submitting ? 'true' : null\"\n [attr.aria-label]=\"'Formul\u00E1rio ' + (config.metadata?.version || '')\"\n [class.canvas-mode-enabled]=\"editModeEnabled\"\n [class.presentation-mode]=\"!!presentationModeGlobal\"\n [class.readonly-mode]=\"!!readonlyModeGlobal\"\n [formGroup]=\"form\"\n [ngClass]=\"{\n 'pres-compact': presentationVars.compact,\n 'pres-label-left': presentationVars.labelPosition === 'left',\n 'pres-label-above': presentationVars.labelPosition === 'above'\n }\"\n [style.--pfx-pres-label-align]=\"presentationVars.labelAlign\"\n [style.--pfx-pres-label-size]=\"presentationVars.labelSize\"\n [style.--pfx-pres-label-width]=\"presentationVars.labelWidth\"\n [style.--pfx-pres-row-gap]=\"presentationVars.density === 'compact' ? '6px' : (presentationVars.density === 'cozy' ? '8px' : '10px')\"\n [style.--pfx-pres-row-padding]=\"presentationVars.density === 'compact' ? '2px 0' : (presentationVars.density === 'cozy' ? '6px 0' : '8px 0')\"\n [style.--pfx-pres-value-align]=\"presentationVars.valueAlign\"\n [style.--pfx-pres-value-size]=\"presentationVars.valueSize\"\n class=\"praxis-dynamic-form\"\n>\n <praxis-canvas-toolbar\n (editMetadata)=\"openSelectedElementEditor()\"\n (selectPath)=\"onSelectPath($event)\"\n (moveUp)=\"onToolbarMove('up')\"\n (moveDown)=\"onToolbarMove('down')\"\n (toggleReadonly)=\"onToolbarToggleReadonly()\"\n (toggleRequired)=\"onToolbarToggleRequired()\"\n (toggleHidden)=\"onToolbarToggleHidden()\"\n (toggleDisabled)=\"onToolbarToggleDisabled()\"\n (requestClose)=\"onToolbarRequestClose()\"\n *ngIf=\"editModeEnabled && selectedElement\"\n [selectedElement]=\"selectedElement\"\n [style.transform]=\"toolbarTransform\"\n ></praxis-canvas-toolbar>\n\n @if ((config.actions?.placement || 'insideLastSection') === 'top' && !(presentationModeGlobal || readonlyModeGlobal)) {\n <praxis-form-actions\n [actions]=\"config.actions\"\n [isSubmitting]=\"submitting\"\n [formIsValid]=\"form.valid\"\n [submitError]=\"submitError\"\n [formId]=\"formId\"\n (action)=\"onFormAction($event)\"\n ></praxis-form-actions>\n }\n\n @for (section of config.sections; track (section.id ?? $index); let sectionIndex = $index;\n let last = $last) {\n <div\n class=\"section-drop-wrapper\"\n [attr.data-section-id]=\"section.id\"\n >\n <div\n #sectionEl\n class=\"form-section canvas-element\"\n data-canvas-type=\"section\"\n [attr.data-section-id]=\"section.id\"\n [attr.data-section-index]=\"sectionIndex\"\n (mouseenter)=\"onElementMouseEnter($event, 'section', section, sectionEl)\"\n (mouseleave)=\"onElementMouseLeave($event)\"\n (click)=\"onElementClick($event, 'section', section, sectionEl)\"\n [class.selected]=\"selectedElement?.domElement === sectionEl\"\n [class.hovered]=\"hoveredElement?.domElement === sectionEl && selectedElement?.domElement !== sectionEl\"\n [style.marginBottom.px]=\"!last ? (section.gapBottom || null) : null\"\n >\n @if (section.title) {\n <h3\n class=\"section-title\"\n [class.title-large]=\"section.titleStyle === 'titleLarge'\"\n [class.title-medium]=\"section.titleStyle === 'titleMedium'\"\n [class.title-small]=\"section.titleStyle === 'titleSmall'\"\n [class.headline-small]=\"section.titleStyle === 'headlineSmall'\"\n [style.marginBottom.px]=\"section.titleGapBottom || null\"\n >\n @if (section.icon) {\n <mat-icon class=\"section-title-icon\" aria-hidden=\"true\" [praxisIcon]=\"section.icon\"></mat-icon>\n }\n {{ section.title }}\n </h3>\n } @if (section.description) {\n <p\n class=\"section-description\"\n [class.body-large]=\"section.descriptionStyle === 'bodyLarge'\"\n [class.body-medium]=\"section.descriptionStyle === 'bodyMedium'\"\n [class.body-small]=\"section.descriptionStyle === 'bodySmall'\"\n [style.marginBottom.px]=\"section.descriptionGapBottom || null\"\n >\n {{ section.description }}\n </p>\n } @for (row of section.rows; track (row.id ?? $index); let rowIndex = $index) {\n <div\n class=\"row-drop-wrapper\"\n [attr.data-section-id]=\"section.id\"\n >\n <div\n #rowEl\n class=\"form-row grid-12 canvas-element\"\n data-canvas-type=\"row\"\n [attr.data-row-index]=\"rowIndex\"\n [attr.data-section-id]=\"section.id\"\n [attr.data-row-id]=\"row.id\"\n [style.--pfx-grid-gap.px]=\"row.gap || null\"\n [style.marginBottom.px]=\"row.rowGap || null\"\n (mouseenter)=\"onElementMouseEnter($event, 'row', row, rowEl)\"\n (mouseleave)=\"onElementMouseLeave($event)\"\n (click)=\"onElementClick($event, 'row', row, rowEl)\"\n [class.selected]=\"selectedElement?.domElement === rowEl\"\n [class.hovered]=\"hoveredElement?.domElement === rowEl && selectedElement?.domElement !== rowEl\"\n >\n @for (column of row.columns; track (column.id ?? $index); let colIndex = $index) {\n @if (isColumnVisible(column)) {\n <div\n class=\"column-drop-wrapper\"\n [attr.data-section-id]=\"section.id\"\n [attr.data-row-id]=\"row.id\"\n >\n <div\n #colEl\n class=\"form-column canvas-element\"\n [ngClass]=\"getColumnClasses(column)\"\n [style.padding.px]=\"column.padding\"\n [attr.data-testid]=\"column.testId || null\"\n data-canvas-type=\"column\"\n [attr.data-column-index]=\"colIndex\"\n [attr.data-row-index]=\"rowIndex\"\n [attr.data-section-id]=\"section.id\"\n [attr.data-row-id]=\"row.id\"\n [attr.data-column-id]=\"column.id\"\n (mouseenter)=\"onElementMouseEnter($event, 'column', column, colEl)\"\n (mouseleave)=\"onElementMouseLeave($event)\"\n (click)=\"onElementClick($event, 'column', column, colEl)\"\n [class.selected]=\"selectedElement?.domElement === colEl\"\n [class.hovered]=\"hoveredElement?.domElement === colEl && selectedElement?.domElement !== colEl\"\n >\n <ng-container\n dynamicFieldLoader\n [fields]=\"getColumnFields(column)\"\n [formGroup]=\"form\"\n [readonlyMode]=\"readonlyModeGlobal === null ? null : readonlyModeGlobal\"\n [disabledMode]=\"disabledModeGlobal === null ? null : disabledModeGlobal\"\n [presentationMode]=\"presentationModeGlobal === null ? null : presentationModeGlobal\"\n [visible]=\"visibleGlobal === null ? null : visibleGlobal\"\n [canvasMode]=\"editModeEnabled\"\n (canvasMouseEnter)=\"onFieldMouseEnter($event)\"\n (canvasMouseLeave)=\"onFieldMouseLeave($event)\"\n (canvasClick)=\"onFieldClick($event)\"\n >\n </ng-container>\n </div>\n </div>\n } }\n </div>\n </div>\n\n }\n @if ((config.actions?.placement || 'insideLastSection') === 'insideLastSection' && last && !(presentationModeGlobal || readonlyModeGlobal)) {\n <praxis-form-actions\n [actions]=\"config.actions\"\n [isSubmitting]=\"submitting\"\n [formIsValid]=\"form.valid\"\n [submitError]=\"submitError\"\n [formId]=\"formId\"\n (action)=\"onFormAction($event)\"\n ></praxis-form-actions>\n }\n <!-- Overlay de bloqueio durante submiss\u00E3o -->\n @if (submitting) {\n <div class=\"form-blocking-overlay\" aria-live=\"polite\">\n <mat-progress-spinner\n diameter=\"40\"\n color=\"primary\"\n ></mat-progress-spinner>\n <p>{{ config.messages?.loading?.submit || 'Salvando...' }}</p>\n </div>\n }\n </div>\n </div>\n\n @if (editModeEnabled && selectedElement?.domElement === sectionEl) {\n <div class=\"add-section-container\">\n <div class=\"add-section-line\"></div>\n <button\n mat-fab\n color=\"primary\"\n aria-label=\"Adicionar nova se\u00E7\u00E3o\"\n (click)=\"addNewSectionAfter(sectionIndex)\"\n matTooltip=\"Adicionar nova se\u00E7\u00E3o aqui\"\n >\n <mat-icon [praxisIcon]=\"'add'\"></mat-icon>\n </button>\n <div class=\"add-section-line\"></div>\n </div>\n } }\n @if ((config.actions?.placement || 'insideLastSection') === 'afterSections' && !(presentationModeGlobal || readonlyModeGlobal)) {\n <praxis-form-actions\n [actions]=\"config.actions\"\n [isSubmitting]=\"submitting\"\n [formIsValid]=\"form.valid\"\n [submitError]=\"submitError\"\n [formId]=\"formId\"\n (action)=\"onFormAction($event)\"\n ></praxis-form-actions>\n }\n</form>\n", styles: ["@charset \"UTF-8\";:host{display:block;position:relative}.form-config-controls{position:absolute;top:4px;right:4px;display:flex;gap:.25rem;z-index:100;background:transparent;padding:0;border:0;min-width:0;justify-content:flex-end;pointer-events:none}.form-config-controls>*{pointer-events:auto}.form-config-controls .mat-icon-button{--mdc-icon-button-state-layer-size: 36px;width:36px;height:36px;color:var(--md-sys-color-on-surface-variant)}.form-config-controls .mat-icon-button:hover{color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary),transparent 90%)}.config-button{color:var(--md-sys-color-primary)}.form-loading{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:3rem;text-align:center;color:var(--md-sys-color-on-surface);gap:1rem}.form-loading p{margin:0;font-size:.875rem;opacity:.7}.form-error{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:3rem;text-align:center;color:var(--md-sys-color-error);gap:1rem;border:1px solid var(--md-sys-color-error);border-radius:8px;background-color:var(--md-sys-color-error-container);margin:1rem}.form-error h3{margin:0;color:var(--md-sys-color-on-error-container)}.form-error p{margin:0;color:var(--md-sys-color-on-error-container);opacity:.8}.form-error button{margin-top:.5rem}.praxis-dynamic-form{display:flex;flex-direction:column;transition:all .3s ease;position:relative}.praxis-dynamic-form.presentation-mode .form-row,.praxis-dynamic-form.readonly-mode .form-row{gap:.5rem;margin-bottom:.5rem}.praxis-dynamic-form.presentation-mode .form-section,.praxis-dynamic-form.readonly-mode .form-section{padding:.75rem .875rem}.praxis-dynamic-form.pres-compact .form-row{gap:.35rem;margin-bottom:.35rem}.praxis-dynamic-form.pres-compact .form-section{padding:.5rem .75rem}.praxis-dynamic-form.pres-label-left .praxis-presentation{display:grid;grid-template-columns:var(--pfx-presentation-label-w, 220px) 1fr;align-items:baseline;column-gap:10px}.praxis-dynamic-form.pres-label-left .praxis-presentation__label{text-align:right;margin-bottom:0}.form-section{border:1px solid var(--pfx-form-stroke, var(--md-sys-color-outline-variant));border-radius:8px;padding:1rem;background:var(--pfx-form-section-surface, var(--md-sys-color-surface-container));transition:all .2s ease;position:relative}.section-drop-wrapper>.form-section{margin-bottom:var(--pfx-section-gap, 20px)}.section-drop-wrapper:last-of-type>.form-section{margin-bottom:0}.section-title{margin:0 0 6px;font-size:1.05rem;font-weight:500;color:var(--md-sys-color-on-surface)}.section-title.title-large{font:var(--mdc-typography-title-large, 500 22px/28px system-ui)}.section-title.title-medium{font:var(--mdc-typography-title-medium, 500 16px/24px system-ui)}.section-title.title-small{font:var(--mdc-typography-title-small, 500 14px/20px system-ui)}.section-title.headline-small{font:var(--mdc-typography-headline-small, 600 24px/32px system-ui)}.section-description{margin:0 0 8px;font-size:.875rem;color:var(--md-sys-color-on-surface-variant)}.section-description.body-large{font:var(--mdc-typography-body-large, 400 16px/24px system-ui)}.section-description.body-medium{font:var(--mdc-typography-body-medium, 400 14px/20px system-ui)}.section-description.body-small{font:var(--mdc-typography-body-small, 400 12px/16px system-ui)}.form-row{display:flex;gap:1rem;margin-bottom:1rem;transition:all .2s ease;border-radius:6px;position:relative}.form-row:last-child{margin-bottom:0}.form-column{flex:1;min-width:0;transition:all .2s ease;border-radius:4px;position:relative}.form-row.grid-12{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:var(--pfx-grid-gap, 16px)}.align-start{align-self:flex-start}.align-center{align-self:center}.align-end{align-self:flex-end}.align-stretch{align-self:stretch}.span-xs-1{grid-column:span 1}.span-xs-2{grid-column:span 2}.span-xs-3{grid-column:span 3}.span-xs-4{grid-column:span 4}.span-xs-5{grid-column:span 5}.span-xs-6{grid-column:span 6}.span-xs-7{grid-column:span 7}.span-xs-8{grid-column:span 8}.span-xs-9{grid-column:span 9}.span-xs-10{grid-column:span 10}.span-xs-11{grid-column:span 11}.span-xs-12{grid-column:span 12}.offset-xs-0{margin-left:0%}.offset-xs-1{margin-left:calc(1 / 12 * 100%)}.offset-xs-2{margin-left:calc(2 / 12 * 100%)}.offset-xs-3{margin-left:25%}.offset-xs-4{margin-left:calc(4 / 12 * 100%)}.offset-xs-5{margin-left:calc(5 / 12 * 100%)}.offset-xs-6{margin-left:50%}.offset-xs-7{margin-left:calc(7 / 12 * 100%)}.offset-xs-8{margin-left:calc(8 / 12 * 100%)}.offset-xs-9{margin-left:75%}.offset-xs-10{margin-left:calc(10 / 12 * 100%)}.offset-xs-11{margin-left:calc(11 / 12 * 100%)}.order-xs--12{order:-12}.order-xs--11{order:-11}.order-xs--10{order:-10}.order-xs--9{order:-9}.order-xs--8{order:-8}.order-xs--7{order:-7}.order-xs--6{order:-6}.order-xs--5{order:-5}.order-xs--4{order:-4}.order-xs--3{order:-3}.order-xs--2{order:-2}.order-xs--1{order:-1}.order-xs-0{order:0}.order-xs-1{order:1}.order-xs-2{order:2}.order-xs-3{order:3}.order-xs-4{order:4}.order-xs-5{order:5}.order-xs-6{order:6}.order-xs-7{order:7}.order-xs-8{order:8}.order-xs-9{order:9}.order-xs-10{order:10}.order-xs-11{order:11}.order-xs-12{order:12}.hidden-xs{display:none}@media (min-width: 600px){.span-sm-1{grid-column:span 1}.span-sm-2{grid-column:span 2}.span-sm-3{grid-column:span 3}.span-sm-4{grid-column:span 4}.span-sm-5{grid-column:span 5}.span-sm-6{grid-column:span 6}.span-sm-7{grid-column:span 7}.span-sm-8{grid-column:span 8}.span-sm-9{grid-column:span 9}.span-sm-10{grid-column:span 10}.span-sm-11{grid-column:span 11}.span-sm-12{grid-column:span 12}.offset-sm-0{margin-left:0%}.offset-sm-1{margin-left:calc(1 / 12 * 100%)}.offset-sm-2{margin-left:calc(2 / 12 * 100%)}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:calc(4 / 12 * 100%)}.offset-sm-5{margin-left:calc(5 / 12 * 100%)}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:calc(7 / 12 * 100%)}.offset-sm-8{margin-left:calc(8 / 12 * 100%)}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:calc(10 / 12 * 100%)}.offset-sm-11{margin-left:calc(11 / 12 * 100%)}.order-sm--12{order:-12}.order-sm--11{order:-11}.order-sm--10{order:-10}.order-sm--9{order:-9}.order-sm--8{order:-8}.order-sm--7{order:-7}.order-sm--6{order:-6}.order-sm--5{order:-5}.order-sm--4{order:-4}.order-sm--3{order:-3}.order-sm--2{order:-2}.order-sm--1{order:-1}.order-sm-0{order:0}.order-sm-1{order:1}.order-sm-2{order:2}.order-sm-3{order:3}.order-sm-4{order:4}.order-sm-5{order:5}.order-sm-6{order:6}.order-sm-7{order:7}.order-sm-8{order:8}.order-sm-9{order:9}.order-sm-10{order:10}.order-sm-11{order:11}.order-sm-12{order:12}.hidden-sm{display:none}}@media (min-width: 900px){.span-md-1{grid-column:span 1}.span-md-2{grid-column:span 2}.span-md-3{grid-column:span 3}.span-md-4{grid-column:span 4}.span-md-5{grid-column:span 5}.span-md-6{grid-column:span 6}.span-md-7{grid-column:span 7}.span-md-8{grid-column:span 8}.span-md-9{grid-column:span 9}.span-md-10{grid-column:span 10}.span-md-11{grid-column:span 11}.span-md-12{grid-column:span 12}.offset-md-0{margin-left:0%}.offset-md-1{margin-left:calc(1 / 12 * 100%)}.offset-md-2{margin-left:calc(2 / 12 * 100%)}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:calc(4 / 12 * 100%)}.offset-md-5{margin-left:calc(5 / 12 * 100%)}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:calc(7 / 12 * 100%)}.offset-md-8{margin-left:calc(8 / 12 * 100%)}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:calc(10 / 12 * 100%)}.offset-md-11{margin-left:calc(11 / 12 * 100%)}.order-md--12{order:-12}.order-md--11{order:-11}.order-md--10{order:-10}.order-md--9{order:-9}.order-md--8{order:-8}.order-md--7{order:-7}.order-md--6{order:-6}.order-md--5{order:-5}.order-md--4{order:-4}.order-md--3{order:-3}.order-md--2{order:-2}.order-md--1{order:-1}.order-md-0{order:0}.order-md-1{order:1}.order-md-2{order:2}.order-md-3{order:3}.order-md-4{order:4}.order-md-5{order:5}.order-md-6{order:6}.order-md-7{order:7}.order-md-8{order:8}.order-md-9{order:9}.order-md-10{order:10}.order-md-11{order:11}.order-md-12{order:12}.hidden-md{display:none}}@media (min-width: 1200px){.span-lg-1{grid-column:span 1}.span-lg-2{grid-column:span 2}.span-lg-3{grid-column:span 3}.span-lg-4{grid-column:span 4}.span-lg-5{grid-column:span 5}.span-lg-6{grid-column:span 6}.span-lg-7{grid-column:span 7}.span-lg-8{grid-column:span 8}.span-lg-9{grid-column:span 9}.span-lg-10{grid-column:span 10}.span-lg-11{grid-column:span 11}.span-lg-12{grid-column:span 12}.offset-lg-0{margin-left:0%}.offset-lg-1{margin-left:calc(1 / 12 * 100%)}.offset-lg-2{margin-left:calc(2 / 12 * 100%)}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:calc(4 / 12 * 100%)}.offset-lg-5{margin-left:calc(5 / 12 * 100%)}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:calc(7 / 12 * 100%)}.offset-lg-8{margin-left:calc(8 / 12 * 100%)}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:calc(10 / 12 * 100%)}.offset-lg-11{margin-left:calc(11 / 12 * 100%)}.order-lg--12{order:-12}.order-lg--11{order:-11}.order-lg--10{order:-10}.order-lg--9{order:-9}.order-lg--8{order:-8}.order-lg--7{order:-7}.order-lg--6{order:-6}.order-lg--5{order:-5}.order-lg--4{order:-4}.order-lg--3{order:-3}.order-lg--2{order:-2}.order-lg--1{order:-1}.order-lg-0{order:0}.order-lg-1{order:1}.order-lg-2{order:2}.order-lg-3{order:3}.order-lg-4{order:4}.order-lg-5{order:5}.order-lg-6{order:6}.order-lg-7{order:7}.order-lg-8{order:8}.order-lg-9{order:9}.order-lg-10{order:10}.order-lg-11{order:11}.order-lg-12{order:12}.hidden-lg{display:none}}@media (min-width: 1536px){.span-xl-1{grid-column:span 1}.span-xl-2{grid-column:span 2}.span-xl-3{grid-column:span 3}.span-xl-4{grid-column:span 4}.span-xl-5{grid-column:span 5}.span-xl-6{grid-column:span 6}.span-xl-7{grid-column:span 7}.span-xl-8{grid-column:span 8}.span-xl-9{grid-column:span 9}.span-xl-10{grid-column:span 10}.span-xl-11{grid-column:span 11}.span-xl-12{grid-column:span 12}.offset-xl-0{margin-left:0%}.offset-xl-1{margin-left:calc(1 / 12 * 100%)}.offset-xl-2{margin-left:calc(2 / 12 * 100%)}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:calc(4 / 12 * 100%)}.offset-xl-5{margin-left:calc(5 / 12 * 100%)}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:calc(7 / 12 * 100%)}.offset-xl-8{margin-left:calc(8 / 12 * 100%)}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:calc(10 / 12 * 100%)}.offset-xl-11{margin-left:calc(11 / 12 * 100%)}.order-xl--12{order:-12}.order-xl--11{order:-11}.order-xl--10{order:-10}.order-xl--9{order:-9}.order-xl--8{order:-8}.order-xl--7{order:-7}.order-xl--6{order:-6}.order-xl--5{order:-5}.order-xl--4{order:-4}.order-xl--3{order:-3}.order-xl--2{order:-2}.order-xl--1{order:-1}.order-xl-0{order:0}.order-xl-1{order:1}.order-xl-2{order:2}.order-xl-3{order:3}.order-xl-4{order:4}.order-xl-5{order:5}.order-xl-6{order:6}.order-xl-7{order:7}.order-xl-8{order:8}.order-xl-9{order:9}.order-xl-10{order:10}.order-xl-11{order:11}.order-xl-12{order:12}.hidden-xl{display:none}}.form-blocking-overlay{position:absolute;inset:0;background:transparent;color:var(--md-sys-color-on-surface, #000);backdrop-filter:blur(2px) saturate(103%);-webkit-backdrop-filter:blur(2px) saturate(103%);display:flex;align-items:center;justify-content:center;flex-direction:column;gap:12px;z-index:10;pointer-events:all}@media (max-width: 768px){.form-row{flex-direction:column;gap:.5rem}.form-section{padding:1rem}}.canvas-mode-enabled{--canvas-hit: 14px}.canvas-mode-enabled .canvas-element{position:relative;z-index:0;border-radius:8px;outline:2px solid transparent;outline-offset:2px;transition:outline-color .2s ease,outline-style .2s ease}.canvas-mode-enabled .canvas-element:before{content:\"\";position:absolute;inset:calc(-1 * var(--canvas-hit));pointer-events:none;border-radius:inherit;background:transparent}.canvas-mode-enabled .canvas-element[data-canvas-type=section]{--outline-color: #4285f4}.canvas-mode-enabled .canvas-element[data-canvas-type=row]{--outline-color: #9c27b0}.canvas-mode-enabled .canvas-element[data-canvas-type=column]{--outline-color: #00bcd4}.canvas-mode-enabled .canvas-element[data-canvas-type=field]{--outline-color: #4caf50}.canvas-mode-enabled .canvas-element[data-canvas-type=actions]{--outline-color: #ff9800}.canvas-mode-enabled .canvas-element.hovered:not(.selected){outline-color:var(--outline-color, #3f51b5);outline-style:dashed}.canvas-mode-enabled .canvas-element.selected{outline-color:var(--outline-color, #3f51b5);outline-style:solid;box-shadow:0 0 0 2px color-mix(in oklab,var(--outline-color, #3f51b5) 70%,transparent),0 0 8px color-mix(in oklab,var(--outline-color, #3f51b5) 60%,transparent),0 0 18px color-mix(in oklab,var(--outline-color, #3f51b5) 35%,transparent)}.canvas-mode-enabled .canvas-element.hovered{z-index:1000}.canvas-mode-enabled .canvas-element.selected{z-index:2000}.section-drop-wrapper,.row-drop-wrapper,.column-drop-wrapper{display:contents}.add-section-container{display:flex;align-items:center;justify-content:center;padding:.5rem 0;margin:-.5rem 0;position:relative;z-index:500}.add-section-container .add-section-line{flex-grow:1;height:1px;background:repeating-linear-gradient(90deg,var(--md-sys-color-outline-variant),var(--md-sys-color-outline-variant) 4px,transparent 4px,transparent 8px)}.add-section-container button{margin:0 1rem;transform:scale(.85)}.section-title{display:flex;align-items:center;gap:8px}.section-title .section-title-icon{font-size:1.25em;line-height:1}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: DynamicFieldLoaderDirective, selector: "[dynamicFieldLoader]", inputs: ["fields", "formGroup", "enableExternalControlBinding", "itemTemplate", "readonlyMode", "disabledMode", "presentationMode", "visible", "canvasMode"], outputs: ["componentsCreated", "fieldCreated", "fieldDestroyed", "canvasMouseEnter", "canvasMouseLeave", "canvasClick"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.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: i3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i3.MatFabButton, selector: "button[mat-fab], a[mat-fab], button[matFab], a[matFab]", inputs: ["extended"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i14.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i5$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatDialogModule }, { kind: "ngmodule", type: MatSnackBarModule }, { kind: "ngmodule", type: MatBadgeModule }, { kind: "directive", type: i16.MatBadge, selector: "[matBadge]", inputs: ["matBadgeColor", "matBadgeOverlap", "matBadgeDisabled", "matBadgePosition", "matBadge", "matBadgeDescription", "matBadgeSize", "matBadgeHidden"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "component", type: CanvasToolbarComponent, selector: "praxis-canvas-toolbar", inputs: ["selectedElement"], outputs: ["editMetadata", "delete", "moveUp", "moveDown", "selectPath", "requestClose", "toggleReadonly", "toggleRequired", "toggleHidden", "toggleDisabled"] }, { kind: "component", type: PraxisFormActionsComponent, selector: "praxis-form-actions", inputs: ["actions", "isSubmitting", "formIsValid", "submitError", "formId"], outputs: ["action"] }, { kind: "component", type: EmptyStateCardComponent, selector: "praxis-empty-state-card", inputs: ["icon", "title", "description", "primaryAction", "secondaryActions", "inline"] }] });
9937
10060
  }
9938
10061
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: PraxisDynamicForm, decorators: [{
@@ -9959,7 +10082,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImpor
9959
10082
  }] }, { type: undefined, decorators: [{
9960
10083
  type: Inject,
9961
10084
  args: [CONNECTION_STORAGE]
9962
- }] }, { type: i1$2.DynamicFormService }, { type: i8$2.MatSnackBar }, { type: CanvasStateService }, { type: DynamicFormLayoutService }, { type: i1$2.ErrorMessageService }, { type: i1$2.SchemaNormalizerService }, { type: i1$2.ComponentMetadataRegistry }, { type: i1$2.GlobalConfigService }, { type: i1$2.FormHooksRegistry, decorators: [{
10085
+ }] }, { type: i1$2.DynamicFormService }, { type: i8$3.MatSnackBar }, { type: CanvasStateService }, { type: DynamicFormLayoutService }, { type: i1$2.ErrorMessageService }, { type: i1$2.SchemaNormalizerService }, { type: i1$2.ComponentMetadataRegistry }, { type: i1$2.GlobalConfigService }, { type: i1$2.FormHooksRegistry, decorators: [{
9963
10086
  type: Optional
9964
10087
  }] }, { type: undefined, decorators: [{
9965
10088
  type: Optional