@praxisui/metadata-editor 1.0.0-beta.3 → 1.0.0-beta.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # @praxisui/metadata-editor
2
2
 
3
+ ## 🔰 Exemplos / Quickstart
4
+
5
+ Para ver esta biblioteca em funcionamento em uma aplicação completa, utilize o projeto de exemplo (Quickstart):
6
+
7
+ - Repositório: https://github.com/codexrodrigues/praxis-ui-quickstart
8
+ - O Quickstart demonstra a integração das bibliotecas `@praxisui/*` em um app Angular, incluindo instalação, configuração e uso em telas reais.
9
+
3
10
  Editores de metadados (configurações de campos) do Praxis UI. Esta biblioteca não renderiza campos de formulário em runtime; ela oferece UI e serviços para editar as propriedades (metadata) dos campos, incluindo um renderizador dinâmico de editores e uma aba para gerir regras de cascata entre campos.
4
11
 
5
12
  Documentação de arquitetura: `docs/metadata-editors-architecture.praxis.md`.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Injectable, inject, Component, Input, EventEmitter, Output, signal } from '@angular/core';
2
+ import { Injectable, inject, Component, Input, HostBinding, EventEmitter, Output, signal } from '@angular/core';
3
3
  import * as i3 from '@angular/forms';
4
4
  import { FormControl, FormGroup, ReactiveFormsModule, FormsModule } from '@angular/forms';
5
5
  import * as i3$1 from '@angular/common';
@@ -19,6 +19,8 @@ import * as i8 from '@angular/material/tooltip';
19
19
  import { MatTooltipModule } from '@angular/material/tooltip';
20
20
  import * as i2 from '@angular/material/list';
21
21
  import { MatListModule } from '@angular/material/list';
22
+ import * as i6$1 from '@angular/material/slide-toggle';
23
+ import { MatSlideToggleModule } from '@angular/material/slide-toggle';
22
24
  import { SETTINGS_PANEL_DATA } from '@praxisui/settings-panel';
23
25
  import { BehaviorSubject } from 'rxjs';
24
26
  import * as i7 from '@angular/material/input';
@@ -404,6 +406,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImpor
404
406
  class DynamicEditorRendererComponent {
405
407
  dialog;
406
408
  iconPicker;
409
+ /** Força todos os campos a ocuparem 100% da largura do container. */
410
+ fullWidth = false;
411
+ get fullwidthClass() { return !!this.fullWidth; }
407
412
  properties = [];
408
413
  form;
409
414
  fields = [];
@@ -616,7 +621,7 @@ class DynamicEditorRendererComponent {
616
621
  }
617
622
  }
618
623
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: DynamicEditorRendererComponent, deps: [{ token: i1.MatDialog }, { token: i2$1.IconPickerService }], target: i0.ɵɵFactoryTarget.Component });
619
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.4", type: DynamicEditorRendererComponent, isStandalone: true, selector: "praxis-dynamic-editor-renderer", inputs: { properties: "properties", form: "form" }, usesOnChanges: true, ngImport: i0, template: `
624
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.4", type: DynamicEditorRendererComponent, isStandalone: true, selector: "praxis-dynamic-editor-renderer", inputs: { fullWidth: "fullWidth", properties: "properties", form: "form" }, host: { properties: { "class.fullwidth": "this.fullwidthClass" } }, usesOnChanges: true, ngImport: i0, template: `
620
625
  <ng-template #item let-field="field" let-index="index" let-content="content">
621
626
  <div class="editor-item" style="position: relative;">
622
627
  <ng-container [ngTemplateOutlet]="content"></ng-container>
@@ -670,7 +675,7 @@ class DynamicEditorRendererComponent {
670
675
  </mat-expansion-panel>
671
676
  </mat-accordion>
672
677
  </div>
673
- `, isInline: true, styles: [":host{display:block}.editor-surface{padding:8px 8px 2px;border-radius:12px;background:transparent}.section-accordion{display:block}.section-card{margin:6px 0 8px;border-radius:12px;border:1px solid var(--md-sys-color-outline-variant);overflow:hidden}.section-card.mat-expanded{border-color:color-mix(in srgb,var(--mat-sys-primary, #3f51b5) 20%,transparent);box-shadow:0 2px 10px #0000000d}.section-card .mat-expansion-panel-body{padding:12px 12px 8px;background:linear-gradient(180deg,color-mix(in srgb,var(--md-sys-color-surface, var(--sicoob-bg-elev-1)) 2%),transparent)}.section-header{background:linear-gradient(180deg,color-mix(in srgb,var(--md-sys-color-surface, var(--sicoob-bg-elev-2)) 92%,var(--md-sys-color-primary, var(--sicoob-primary-default))) 0%,var(--md-sys-color-surface, var(--sicoob-bg-elev-2)) 100%);border-bottom:1px solid var(--md-sys-color-outline-variant, var(--sicoob-stroke-medium));padding:2px 8px;min-height:32px;display:flex;align-items:center;color:var(--md-sys-color-on-surface)}.section-header .mat-expansion-panel-header-title,.section-header .mat-expansion-panel-header-description{display:flex;align-items:center;color:var(--md-sys-color-on-surface)}.section-title{display:inline-flex;align-items:center;gap:6px;font-weight:600;letter-spacing:.2px;color:var(--md-sys-color-on-surface);font-size:.9rem;line-height:1.2}.section-icon{color:var(--mat-sys-color-primary, var(--md-sys-color-primary, #3f51b5));opacity:.9}.editor-row{display:flex;gap:12px;align-items:flex-start;flex-wrap:wrap;margin-bottom:8px}.editor-row>praxis-field-shell{flex:1 1 100%;min-width:280px}.editor-row praxis-field-shell .mat-mdc-form-field{width:100%;margin-bottom:8px}.editor-row.row-inline>praxis-field-shell{flex:0 0 auto}.editor-row.row-2>praxis-field-shell{flex:1 1 calc(50% - 12px);min-width:260px}.editor-row.row-3>praxis-field-shell{flex:1 1 calc(33.333% - 12px);min-width:220px}.editor-row>praxis-field-shell[data-field-name=controlType],.editor-row>praxis-field-shell[data-field-name=label],.editor-row>praxis-field-shell[data-field-name=placeholder]{flex:1 1 calc(50% - 12px);min-width:300px}praxis-field-shell[data-field-name=label] .mdc-floating-label,praxis-field-shell[data-field-name=placeholder] .mdc-floating-label{font-weight:600}.editor-row>praxis-field-shell[data-field-name=prefix],.editor-row>praxis-field-shell[data-field-name=suffix],.editor-row>praxis-field-shell[data-field-name=prefixIcon],.editor-row>praxis-field-shell[data-field-name=suffixIcon],.editor-row>praxis-field-shell[data-field-name=prefixIconColor],.editor-row>praxis-field-shell[data-field-name=suffixIconColor]{flex:0 0 200px;min-width:160px}.decorator-btn{position:absolute;right:6px;top:8px;z-index:2;color:var(--mat-sys-primary, #3f51b5);opacity:.85}praxis-field-shell[data-field-name=showCharCount] .mdc-switch{transform:scale(1.05)}praxis-field-shell[data-field-name=showCharCount] .mat-mdc-slide-toggle{font-weight:600}praxis-field-shell[data-field-name=controlType] .mat-mdc-form-field-hint{display:flex;align-items:center;gap:8px;background:#ffab001f;border:1px solid rgba(255,171,0,.35);color:#ffca28;padding:8px 10px;border-radius:6px;line-height:1.3;white-space:normal}praxis-field-shell[data-field-name=controlType] .mat-mdc-form-field-hint:before{content:\"\\26a0\\fe0f\";display:inline-block}praxis-field-shell[data-field-name=controlType] .mat-mdc-form-field-subscript-wrapper{margin-top:6px;margin-bottom:10px;min-height:auto}praxis-field-shell[data-field-name=controlType] .mat-mdc-form-field{margin-bottom:16px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.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: MatExpansionModule }, { kind: "directive", type: i5.MatAccordion, selector: "mat-accordion", inputs: ["hideToggle", "displayMode", "togglePosition"], exportAs: ["matAccordion"] }, { kind: "component", type: i5.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i5.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i5.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i6.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i5$1.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatDialogModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }] });
678
+ `, isInline: true, styles: [":host{display:block}:host(.fullwidth) .editor-row.row-2>praxis-field-shell,:host(.fullwidth) .editor-row.row-3>praxis-field-shell,:host(.fullwidth) .editor-row>praxis-field-shell[data-field-name],:host(.fullwidth) .editor-row>praxis-field-shell[data-field-name=controlType],:host(.fullwidth) .editor-row>praxis-field-shell[data-field-name=label],:host(.fullwidth) .editor-row>praxis-field-shell[data-field-name=placeholder],:host(.fullwidth) .editor-row>praxis-field-shell[data-field-name=prefix],:host(.fullwidth) .editor-row>praxis-field-shell[data-field-name=suffix],:host(.fullwidth) .editor-row>praxis-field-shell[data-field-name=prefixIcon],:host(.fullwidth) .editor-row>praxis-field-shell[data-field-name=suffixIcon],:host(.fullwidth) .editor-row>praxis-field-shell[data-field-name=prefixIconColor],:host(.fullwidth) .editor-row>praxis-field-shell[data-field-name=suffixIconColor]{flex:1 1 100%!important;min-width:0!important}.editor-surface{padding:8px 0 2px;border-radius:12px;background:transparent}.section-accordion{display:block}.section-card{margin:6px 0 8px;border-radius:12px;border:1px solid var(--md-sys-color-outline-variant);overflow:hidden}.section-card.mat-expanded{border-color:color-mix(in srgb,var(--mat-sys-primary, #3f51b5) 20%,transparent);box-shadow:0 2px 10px #0000000d}.section-card .mat-expansion-panel-body{background:linear-gradient(180deg,color-mix(in srgb,var(--md-sys-color-surface, var(--sicoob-bg-elev-1)) 2%),transparent)}.section-header{background:linear-gradient(180deg,color-mix(in srgb,var(--md-sys-color-surface, var(--sicoob-bg-elev-2)) 92%,var(--md-sys-color-primary, var(--sicoob-primary-default))) 0%,var(--md-sys-color-surface, var(--sicoob-bg-elev-2)) 100%);border-bottom:1px solid var(--md-sys-color-outline-variant, var(--sicoob-stroke-medium));padding:2px 8px;min-height:32px;display:flex;align-items:center;color:var(--md-sys-color-on-surface)}.section-header .mat-expansion-panel-header-title,.section-header .mat-expansion-panel-header-description{display:flex;align-items:center;color:var(--md-sys-color-on-surface)}.section-title{display:inline-flex;align-items:center;gap:6px;font-weight:600;letter-spacing:.2px;color:var(--md-sys-color-on-surface);font-size:.9rem;line-height:1.2}.section-icon{color:var(--mat-sys-color-primary, var(--md-sys-color-primary, #3f51b5));opacity:.9}.editor-row{display:flex;gap:12px;align-items:flex-start;flex-wrap:wrap;margin-bottom:8px}.editor-row>praxis-field-shell{flex:1 1 100%;min-width:280px}.editor-row praxis-field-shell .mat-mdc-form-field{width:100%;margin-bottom:8px}.editor-row.row-inline>praxis-field-shell{flex:0 0 auto}.editor-row.row-2>praxis-field-shell{flex:1 1 calc(50% - 12px);min-width:260px}.editor-row.row-3>praxis-field-shell{flex:1 1 calc(33.333% - 12px);min-width:220px}.editor-row>praxis-field-shell[data-field-name=controlType],.editor-row>praxis-field-shell[data-field-name=label],.editor-row>praxis-field-shell[data-field-name=placeholder]{flex:1 1 calc(50% - 12px);min-width:300px}praxis-field-shell[data-field-name=label] .mdc-floating-label,praxis-field-shell[data-field-name=placeholder] .mdc-floating-label{font-weight:600}.editor-row>praxis-field-shell[data-field-name=prefix],.editor-row>praxis-field-shell[data-field-name=suffix],.editor-row>praxis-field-shell[data-field-name=prefixIcon],.editor-row>praxis-field-shell[data-field-name=suffixIcon],.editor-row>praxis-field-shell[data-field-name=prefixIconColor],.editor-row>praxis-field-shell[data-field-name=suffixIconColor]{flex:0 0 200px;min-width:160px}.decorator-btn{position:absolute;right:6px;top:8px;z-index:2;color:var(--mat-sys-primary, #3f51b5);opacity:.85}praxis-field-shell[data-field-name=showCharCount] .mdc-switch{transform:scale(1.05)}praxis-field-shell[data-field-name=showCharCount] .mat-mdc-slide-toggle{font-weight:600}praxis-field-shell[data-field-name=controlType] .mat-mdc-form-field-hint{display:flex;align-items:center;gap:8px;background:#ffab001f;border:1px solid rgba(255,171,0,.35);color:#ffca28;padding:8px 10px;border-radius:6px;line-height:1.3;white-space:normal}praxis-field-shell[data-field-name=controlType] .mat-mdc-form-field-hint:before{content:\"\\26a0\\fe0f\";display:inline-block}praxis-field-shell[data-field-name=controlType] .mat-mdc-form-field-subscript-wrapper{margin-top:6px;margin-bottom:10px;min-height:auto}praxis-field-shell[data-field-name=controlType] .mat-mdc-form-field{margin-bottom:16px}:host(.fullwidth) .editor-row>praxis-field-shell{flex:1 1 100%!important;min-width:0!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.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: MatExpansionModule }, { kind: "directive", type: i5.MatAccordion, selector: "mat-accordion", inputs: ["hideToggle", "displayMode", "togglePosition"], exportAs: ["matAccordion"] }, { kind: "component", type: i5.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i5.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i5.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i6.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i5$1.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatDialogModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }] });
674
679
  }
675
680
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: DynamicEditorRendererComponent, decorators: [{
676
681
  type: Component,
@@ -738,8 +743,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImpor
738
743
  </mat-expansion-panel>
739
744
  </mat-accordion>
740
745
  </div>
741
- `, styles: [":host{display:block}.editor-surface{padding:8px 8px 2px;border-radius:12px;background:transparent}.section-accordion{display:block}.section-card{margin:6px 0 8px;border-radius:12px;border:1px solid var(--md-sys-color-outline-variant);overflow:hidden}.section-card.mat-expanded{border-color:color-mix(in srgb,var(--mat-sys-primary, #3f51b5) 20%,transparent);box-shadow:0 2px 10px #0000000d}.section-card .mat-expansion-panel-body{padding:12px 12px 8px;background:linear-gradient(180deg,color-mix(in srgb,var(--md-sys-color-surface, var(--sicoob-bg-elev-1)) 2%),transparent)}.section-header{background:linear-gradient(180deg,color-mix(in srgb,var(--md-sys-color-surface, var(--sicoob-bg-elev-2)) 92%,var(--md-sys-color-primary, var(--sicoob-primary-default))) 0%,var(--md-sys-color-surface, var(--sicoob-bg-elev-2)) 100%);border-bottom:1px solid var(--md-sys-color-outline-variant, var(--sicoob-stroke-medium));padding:2px 8px;min-height:32px;display:flex;align-items:center;color:var(--md-sys-color-on-surface)}.section-header .mat-expansion-panel-header-title,.section-header .mat-expansion-panel-header-description{display:flex;align-items:center;color:var(--md-sys-color-on-surface)}.section-title{display:inline-flex;align-items:center;gap:6px;font-weight:600;letter-spacing:.2px;color:var(--md-sys-color-on-surface);font-size:.9rem;line-height:1.2}.section-icon{color:var(--mat-sys-color-primary, var(--md-sys-color-primary, #3f51b5));opacity:.9}.editor-row{display:flex;gap:12px;align-items:flex-start;flex-wrap:wrap;margin-bottom:8px}.editor-row>praxis-field-shell{flex:1 1 100%;min-width:280px}.editor-row praxis-field-shell .mat-mdc-form-field{width:100%;margin-bottom:8px}.editor-row.row-inline>praxis-field-shell{flex:0 0 auto}.editor-row.row-2>praxis-field-shell{flex:1 1 calc(50% - 12px);min-width:260px}.editor-row.row-3>praxis-field-shell{flex:1 1 calc(33.333% - 12px);min-width:220px}.editor-row>praxis-field-shell[data-field-name=controlType],.editor-row>praxis-field-shell[data-field-name=label],.editor-row>praxis-field-shell[data-field-name=placeholder]{flex:1 1 calc(50% - 12px);min-width:300px}praxis-field-shell[data-field-name=label] .mdc-floating-label,praxis-field-shell[data-field-name=placeholder] .mdc-floating-label{font-weight:600}.editor-row>praxis-field-shell[data-field-name=prefix],.editor-row>praxis-field-shell[data-field-name=suffix],.editor-row>praxis-field-shell[data-field-name=prefixIcon],.editor-row>praxis-field-shell[data-field-name=suffixIcon],.editor-row>praxis-field-shell[data-field-name=prefixIconColor],.editor-row>praxis-field-shell[data-field-name=suffixIconColor]{flex:0 0 200px;min-width:160px}.decorator-btn{position:absolute;right:6px;top:8px;z-index:2;color:var(--mat-sys-primary, #3f51b5);opacity:.85}praxis-field-shell[data-field-name=showCharCount] .mdc-switch{transform:scale(1.05)}praxis-field-shell[data-field-name=showCharCount] .mat-mdc-slide-toggle{font-weight:600}praxis-field-shell[data-field-name=controlType] .mat-mdc-form-field-hint{display:flex;align-items:center;gap:8px;background:#ffab001f;border:1px solid rgba(255,171,0,.35);color:#ffca28;padding:8px 10px;border-radius:6px;line-height:1.3;white-space:normal}praxis-field-shell[data-field-name=controlType] .mat-mdc-form-field-hint:before{content:\"\\26a0\\fe0f\";display:inline-block}praxis-field-shell[data-field-name=controlType] .mat-mdc-form-field-subscript-wrapper{margin-top:6px;margin-bottom:10px;min-height:auto}praxis-field-shell[data-field-name=controlType] .mat-mdc-form-field{margin-bottom:16px}\n"] }]
742
- }], ctorParameters: () => [{ type: i1.MatDialog }, { type: i2$1.IconPickerService }], propDecorators: { properties: [{
746
+ `, styles: [":host{display:block}:host(.fullwidth) .editor-row.row-2>praxis-field-shell,:host(.fullwidth) .editor-row.row-3>praxis-field-shell,:host(.fullwidth) .editor-row>praxis-field-shell[data-field-name],:host(.fullwidth) .editor-row>praxis-field-shell[data-field-name=controlType],:host(.fullwidth) .editor-row>praxis-field-shell[data-field-name=label],:host(.fullwidth) .editor-row>praxis-field-shell[data-field-name=placeholder],:host(.fullwidth) .editor-row>praxis-field-shell[data-field-name=prefix],:host(.fullwidth) .editor-row>praxis-field-shell[data-field-name=suffix],:host(.fullwidth) .editor-row>praxis-field-shell[data-field-name=prefixIcon],:host(.fullwidth) .editor-row>praxis-field-shell[data-field-name=suffixIcon],:host(.fullwidth) .editor-row>praxis-field-shell[data-field-name=prefixIconColor],:host(.fullwidth) .editor-row>praxis-field-shell[data-field-name=suffixIconColor]{flex:1 1 100%!important;min-width:0!important}.editor-surface{padding:8px 0 2px;border-radius:12px;background:transparent}.section-accordion{display:block}.section-card{margin:6px 0 8px;border-radius:12px;border:1px solid var(--md-sys-color-outline-variant);overflow:hidden}.section-card.mat-expanded{border-color:color-mix(in srgb,var(--mat-sys-primary, #3f51b5) 20%,transparent);box-shadow:0 2px 10px #0000000d}.section-card .mat-expansion-panel-body{background:linear-gradient(180deg,color-mix(in srgb,var(--md-sys-color-surface, var(--sicoob-bg-elev-1)) 2%),transparent)}.section-header{background:linear-gradient(180deg,color-mix(in srgb,var(--md-sys-color-surface, var(--sicoob-bg-elev-2)) 92%,var(--md-sys-color-primary, var(--sicoob-primary-default))) 0%,var(--md-sys-color-surface, var(--sicoob-bg-elev-2)) 100%);border-bottom:1px solid var(--md-sys-color-outline-variant, var(--sicoob-stroke-medium));padding:2px 8px;min-height:32px;display:flex;align-items:center;color:var(--md-sys-color-on-surface)}.section-header .mat-expansion-panel-header-title,.section-header .mat-expansion-panel-header-description{display:flex;align-items:center;color:var(--md-sys-color-on-surface)}.section-title{display:inline-flex;align-items:center;gap:6px;font-weight:600;letter-spacing:.2px;color:var(--md-sys-color-on-surface);font-size:.9rem;line-height:1.2}.section-icon{color:var(--mat-sys-color-primary, var(--md-sys-color-primary, #3f51b5));opacity:.9}.editor-row{display:flex;gap:12px;align-items:flex-start;flex-wrap:wrap;margin-bottom:8px}.editor-row>praxis-field-shell{flex:1 1 100%;min-width:280px}.editor-row praxis-field-shell .mat-mdc-form-field{width:100%;margin-bottom:8px}.editor-row.row-inline>praxis-field-shell{flex:0 0 auto}.editor-row.row-2>praxis-field-shell{flex:1 1 calc(50% - 12px);min-width:260px}.editor-row.row-3>praxis-field-shell{flex:1 1 calc(33.333% - 12px);min-width:220px}.editor-row>praxis-field-shell[data-field-name=controlType],.editor-row>praxis-field-shell[data-field-name=label],.editor-row>praxis-field-shell[data-field-name=placeholder]{flex:1 1 calc(50% - 12px);min-width:300px}praxis-field-shell[data-field-name=label] .mdc-floating-label,praxis-field-shell[data-field-name=placeholder] .mdc-floating-label{font-weight:600}.editor-row>praxis-field-shell[data-field-name=prefix],.editor-row>praxis-field-shell[data-field-name=suffix],.editor-row>praxis-field-shell[data-field-name=prefixIcon],.editor-row>praxis-field-shell[data-field-name=suffixIcon],.editor-row>praxis-field-shell[data-field-name=prefixIconColor],.editor-row>praxis-field-shell[data-field-name=suffixIconColor]{flex:0 0 200px;min-width:160px}.decorator-btn{position:absolute;right:6px;top:8px;z-index:2;color:var(--mat-sys-primary, #3f51b5);opacity:.85}praxis-field-shell[data-field-name=showCharCount] .mdc-switch{transform:scale(1.05)}praxis-field-shell[data-field-name=showCharCount] .mat-mdc-slide-toggle{font-weight:600}praxis-field-shell[data-field-name=controlType] .mat-mdc-form-field-hint{display:flex;align-items:center;gap:8px;background:#ffab001f;border:1px solid rgba(255,171,0,.35);color:#ffca28;padding:8px 10px;border-radius:6px;line-height:1.3;white-space:normal}praxis-field-shell[data-field-name=controlType] .mat-mdc-form-field-hint:before{content:\"\\26a0\\fe0f\";display:inline-block}praxis-field-shell[data-field-name=controlType] .mat-mdc-form-field-subscript-wrapper{margin-top:6px;margin-bottom:10px;min-height:auto}praxis-field-shell[data-field-name=controlType] .mat-mdc-form-field{margin-bottom:16px}:host(.fullwidth) .editor-row>praxis-field-shell{flex:1 1 100%!important;min-width:0!important}\n"] }]
747
+ }], ctorParameters: () => [{ type: i1.MatDialog }, { type: i2$1.IconPickerService }], propDecorators: { fullWidth: [{
748
+ type: Input
749
+ }], fullwidthClass: [{
750
+ type: HostBinding,
751
+ args: ['class.fullwidth']
752
+ }], properties: [{
743
753
  type: Input
744
754
  }], form: [{
745
755
  type: Input
@@ -750,9 +760,9 @@ const inputProperties = [
750
760
  { name: 'label', label: 'Label', editorType: 'text', placeholder: 'Rótulo do campo', group: 'Geral' },
751
761
  { name: 'placeholder', label: 'Placeholder', editorType: 'text', group: 'Geral' },
752
762
  { name: 'hint', label: 'Hint', editorType: 'text', group: 'Geral' },
753
- { name: 'prefixIcon', label: 'Ícone (prefixo)', editorType: 'text', group: 'Geral', hint: "Material Symbols (ex.: mi:search). Use o seletor ao lado para buscar." },
763
+ { name: 'prefixIcon', label: 'Ícone (prefixo)', editorType: 'text', group: 'Geral', hint: "Material Symbols (mi:*). Use o seletor ao lado." },
754
764
  { name: 'prefixIconColor', label: 'Cor do ícone (prefixo)', editorType: 'color', group: 'Geral', hint: 'primary/accent/warn ou cor CSS (ex.: #496ddb, rgb(73,109,219), red)' },
755
- { name: 'suffixIcon', label: 'Ícone (sufixo)', editorType: 'text', group: 'Geral', hint: "Material Symbols (ex.: mi:info). Use o seletor ao lado para buscar." },
765
+ { name: 'suffixIcon', label: 'Ícone (sufixo)', editorType: 'text', group: 'Geral', hint: "Material Symbols (mi:*). Use o seletor ao lado." },
756
766
  { name: 'suffixIconColor', label: 'Cor do ícone (sufixo)', editorType: 'color', group: 'Geral', hint: 'primary/accent/warn ou cor CSS (ex.: #496ddb, rgb(73,109,219), red)' },
757
767
  { name: 'prefix', label: 'Texto (prefixo)', editorType: 'text', group: 'Geral' },
758
768
  { name: 'suffix', label: 'Texto (sufixo)', editorType: 'text', group: 'Geral' },
@@ -2728,6 +2738,70 @@ const yearInputProperties = [
2728
2738
  { name: 'autoFocus', label: 'Focar automaticamente', editorType: 'checkbox', group: 'Formato/Comportamento' },
2729
2739
  ];
2730
2740
 
2741
+ const avatarProperties = [
2742
+ // Geral
2743
+ { name: 'label', label: 'Label', editorType: 'text', group: 'Geral' },
2744
+ { name: 'hint', label: 'Hint', editorType: 'text', group: 'Geral' },
2745
+ // Fonte de conteúdo (extras)
2746
+ { name: 'extra.imageSrc', label: 'Imagem (URL)', editorType: 'text', group: 'Conteúdo', row: 'conteudo.imagem' },
2747
+ { name: 'extra.imageAlt', label: 'Imagem: alt', editorType: 'text', group: 'Conteúdo', row: 'conteudo.imagem' },
2748
+ { name: 'extra.name', label: 'Nome (gera iniciais)', editorType: 'text', group: 'Conteúdo', hint: 'Usado para gerar iniciais quando "Iniciais" estiver vazio' },
2749
+ { name: 'extra.initials', label: 'Iniciais', editorType: 'text', group: 'Conteúdo', hint: 'Ex.: MB' },
2750
+ { name: 'extra.icon', label: 'Ícone (ligature ou mi:*)', editorType: 'text', group: 'Conteúdo', row: 'conteudo.icones', inline: true, hint: "Material Symbols (ex.: mi:person). Use o seletor ao lado para buscar." },
2751
+ { name: 'extra.defaultIcon', label: 'Ícone padrão (fallback)', editorType: 'text', group: 'Conteúdo', row: 'conteudo.icones', inline: true, hint: 'Será usado quando imagem/ícone/iniciais não forem definidos' },
2752
+ // Aparência (extras)
2753
+ { name: 'extra.class', label: 'CSS classes', editorType: 'text', group: 'Aparência', hint: 'Classes CSS adicionais (separadas por espaço)' },
2754
+ { name: 'extra.style', label: 'Estilo (JSON)', editorType: 'textarea', group: 'Aparência', hint: 'Objeto JSON de estilos (ex.: { "border": "1px solid #ccc" })' },
2755
+ {
2756
+ name: 'extra.themeColor', label: 'Tema', editorType: 'select', group: 'Aparência', options: [
2757
+ { value: 'primary', text: 'Primária' },
2758
+ { value: 'secondary', text: 'Secundária' },
2759
+ { value: 'tertiary', text: 'Terciária' },
2760
+ { value: 'base', text: 'Base' },
2761
+ { value: 'info', text: 'Info' },
2762
+ { value: 'success', text: 'Sucesso' },
2763
+ { value: 'warning', text: 'Atenção' },
2764
+ { value: 'error', text: 'Erro' },
2765
+ { value: 'dark', text: 'Escuro' },
2766
+ { value: 'light', text: 'Claro' },
2767
+ { value: 'inverse', text: 'Inverso' },
2768
+ { value: 'none', text: 'Herdar (nenhum)' },
2769
+ ]
2770
+ },
2771
+ {
2772
+ name: 'extra.size', label: 'Tamanho', editorType: 'select', group: 'Aparência', options: [
2773
+ { value: 'small', text: 'Pequeno' },
2774
+ { value: 'medium', text: 'Médio' },
2775
+ { value: 'large', text: 'Grande' },
2776
+ { value: 'none', text: 'Nenhum (auto)' },
2777
+ ]
2778
+ },
2779
+ {
2780
+ name: 'extra.rounded', label: 'Arredondamento', editorType: 'select', group: 'Aparência', options: [
2781
+ { value: 'full', text: 'Total' },
2782
+ { value: 'large', text: 'Grande' },
2783
+ { value: 'medium', text: 'Médio' },
2784
+ { value: 'small', text: 'Pequeno' },
2785
+ { value: 'none', text: 'Sem raio' },
2786
+ ]
2787
+ },
2788
+ {
2789
+ name: 'extra.fillMode', label: 'Preenchimento', editorType: 'select', group: 'Aparência', options: [
2790
+ { value: 'solid', text: 'Sólido' },
2791
+ { value: 'outline', text: 'Contorno' },
2792
+ { value: 'none', text: 'Nenhum (herdar)' },
2793
+ ]
2794
+ },
2795
+ { name: 'extra.border', label: 'Borda', editorType: 'checkbox', group: 'Aparência', row: 'aparencia.inline1', inline: true },
2796
+ // Acessibilidade / UX
2797
+ { name: 'extra.tooltip', label: 'Tooltip', editorType: 'text', group: 'Acessibilidade' },
2798
+ { name: 'extra.ariaLabel', label: 'ARIA label', editorType: 'text', group: 'Acessibilidade' },
2799
+ // Estados gerais de campo
2800
+ { name: 'readonly', label: 'Somente leitura', editorType: 'checkbox', group: 'Estado' },
2801
+ { name: 'disabled', label: 'Desabilitado', editorType: 'checkbox', group: 'Estado' },
2802
+ { name: 'hidden', label: 'Oculto', editorType: 'checkbox', group: 'Estado' },
2803
+ ];
2804
+
2731
2805
  /** Garante que minLength <= maxLength quando ambos definidos. */
2732
2806
  function minLenLeMaxLen(group) {
2733
2807
  const v = group.value || {};
@@ -2750,6 +2824,7 @@ class FieldMetadataEditorComponent {
2750
2824
  cancel = new EventEmitter();
2751
2825
  form;
2752
2826
  normalizedProps = [];
2827
+ fullWidth = true;
2753
2828
  initialSnapshot = null;
2754
2829
  baselineReady = false;
2755
2830
  // Lista de tipos suportados no editor (curada para os tipos com config disponível)
@@ -2791,6 +2866,7 @@ class FieldMetadataEditorComponent {
2791
2866
  { value: FieldControlType.TRANSFER_LIST, label: 'Transferência de itens' },
2792
2867
  { value: FieldControlType.CPF_CNPJ_INPUT, label: 'CPF/CNPJ' },
2793
2868
  { value: FieldControlType.FILE_UPLOAD, label: 'Upload de Arquivo' },
2869
+ { value: FieldControlType.AVATAR, label: 'Avatar' },
2794
2870
  ];
2795
2871
  // Settings Panel integration (contract: isDirty$, isValid$, isBusy$)
2796
2872
  isDirty$ = new BehaviorSubject(false);
@@ -2987,6 +3063,10 @@ class FieldMetadataEditorComponent {
2987
3063
  this.registry.register(this.controlType, yearInputProperties);
2988
3064
  props = yearInputProperties;
2989
3065
  }
3066
+ else if (this.controlType === FieldControlType.AVATAR) {
3067
+ this.registry.register(this.controlType, avatarProperties);
3068
+ props = avatarProperties;
3069
+ }
2990
3070
  else if (this.controlType === FieldControlType.TREE_SELECT ||
2991
3071
  this.controlType === FieldControlType.MULTI_SELECT_TREE) {
2992
3072
  this.registry.register(this.controlType, treeSelectProperties);
@@ -3289,24 +3369,36 @@ class FieldMetadataEditorComponent {
3289
3369
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: FieldMetadataEditorComponent, deps: [{ token: ConfigRegistryService }, { token: SchemaNormalizerService }, { token: DynamicFormFactoryService }, { token: ContextValidatorRegistryService }], target: i0.ɵɵFactoryTarget.Component });
3290
3370
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.4", type: FieldMetadataEditorComponent, isStandalone: true, selector: "praxis-field-metadata-editor", inputs: { controlType: "controlType", seed: "seed" }, outputs: { applied: "applied", cancel: "cancel" }, ngImport: i0, template: `
3291
3371
  <div class="p-3" *ngIf="form">
3372
+ <div class="meta-toolbar" aria-label="Layout do editor" style="display:flex;align-items:center;gap:8px;margin:0 0 8px;">
3373
+ <mat-slide-toggle [checked]="fullWidth" (change)="fullWidth = $event.checked" [disableRipple]="true">
3374
+ Campos 100% (1 coluna)
3375
+ </mat-slide-toggle>
3376
+ </div>
3292
3377
  <praxis-dynamic-editor-renderer
3293
3378
  [properties]="normalizedProps"
3294
3379
  [form]="form"
3380
+ [fullWidth]="fullWidth"
3295
3381
  ></praxis-dynamic-editor-renderer>
3296
3382
  </div>
3297
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "component", type: DynamicEditorRendererComponent, selector: "praxis-dynamic-editor-renderer", inputs: ["properties", "form"] }] });
3383
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "component", type: DynamicEditorRendererComponent, selector: "praxis-dynamic-editor-renderer", inputs: ["fullWidth", "properties", "form"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i6$1.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"] }] });
3298
3384
  }
3299
3385
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: FieldMetadataEditorComponent, decorators: [{
3300
3386
  type: Component,
3301
3387
  args: [{
3302
3388
  selector: 'praxis-field-metadata-editor',
3303
3389
  standalone: true,
3304
- imports: [CommonModule, ReactiveFormsModule, DynamicEditorRendererComponent],
3390
+ imports: [CommonModule, ReactiveFormsModule, DynamicEditorRendererComponent, MatSlideToggleModule],
3305
3391
  template: `
3306
3392
  <div class="p-3" *ngIf="form">
3393
+ <div class="meta-toolbar" aria-label="Layout do editor" style="display:flex;align-items:center;gap:8px;margin:0 0 8px;">
3394
+ <mat-slide-toggle [checked]="fullWidth" (change)="fullWidth = $event.checked" [disableRipple]="true">
3395
+ Campos 100% (1 coluna)
3396
+ </mat-slide-toggle>
3397
+ </div>
3307
3398
  <praxis-dynamic-editor-renderer
3308
3399
  [properties]="normalizedProps"
3309
3400
  [form]="form"
3401
+ [fullWidth]="fullWidth"
3310
3402
  ></praxis-dynamic-editor-renderer>
3311
3403
  </div>
3312
3404
  `,