@praxisui/stepper 8.0.0-beta.30 → 8.0.0-beta.32

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.
@@ -1,16 +1,16 @@
1
- import * as i1$1 from '@angular/common';
1
+ import * as i1$2 from '@angular/common';
2
2
  import { CommonModule } from '@angular/common';
3
3
  import * as i0 from '@angular/core';
4
4
  import { Inject, Component, EventEmitter, inject, DestroyRef, Injector, ChangeDetectorRef, ViewContainerRef, ViewChild, Output, ChangeDetectionStrategy, Input, signal, ElementRef, Renderer2, effect, computed, TemplateRef, ContentChild, ENVIRONMENT_INITIALIZER, isDevMode } from '@angular/core';
5
5
  import { ActivatedRoute } from '@angular/router';
6
- import * as i2$1 from '@angular/material/stepper';
6
+ import * as i2 from '@angular/material/stepper';
7
7
  import { MatStepperModule } from '@angular/material/stepper';
8
8
  import * as i3$1 from '@angular/material/button';
9
9
  import { MatButtonModule } from '@angular/material/button';
10
10
  import * as i4$1 from '@angular/material/icon';
11
11
  import { MatIconModule } from '@angular/material/icon';
12
12
  import { PraxisIconDirective, providePraxisI18n, PraxisI18nService, IconPickerService, createEmptyRichContentDocument, deepMerge, ASYNC_CONFIG_STORAGE, ComponentKeyService, LoggerService, DynamicWidgetLoaderDirective, EmptyStateCardComponent, EDITORIAL_WIDGET_TAG, ComponentMetadataRegistry, createCorporateLoggerConfig, ConsoleLoggerSink, CONFIG_STORAGE } from '@praxisui/core';
13
- import * as i2 from '@angular/forms';
13
+ import * as i1$1 from '@angular/forms';
14
14
  import { FormsModule, ReactiveFormsModule } from '@angular/forms';
15
15
  import { PraxisDynamicFormConfigEditor, PraxisDynamicForm } from '@praxisui/dynamic-form';
16
16
  import { SETTINGS_PANEL_DATA, SettingsPanelService } from '@praxisui/settings-panel';
@@ -18,15 +18,15 @@ import * as i3 from '@angular/material/form-field';
18
18
  import { MatFormFieldModule } from '@angular/material/form-field';
19
19
  import * as i4 from '@angular/material/input';
20
20
  import { MatInputModule } from '@angular/material/input';
21
- import * as i7 from '@angular/material/slide-toggle';
21
+ import * as i6 from '@angular/material/slide-toggle';
22
22
  import { MatSlideToggleModule } from '@angular/material/slide-toggle';
23
- import * as i8 from '@angular/cdk/drag-drop';
23
+ import * as i7 from '@angular/cdk/drag-drop';
24
24
  import { moveItemInArray, DragDropModule } from '@angular/cdk/drag-drop';
25
- import * as i9 from '@angular/material/tooltip';
25
+ import * as i8 from '@angular/material/tooltip';
26
26
  import { MatTooltipModule } from '@angular/material/tooltip';
27
27
  import * as i1 from '@angular/material/dialog';
28
28
  import { MAT_DIALOG_DATA, MatDialogModule, MatDialog } from '@angular/material/dialog';
29
- import * as i10 from '@angular/material/tabs';
29
+ import * as i9 from '@angular/material/tabs';
30
30
  import { MatTabsModule } from '@angular/material/tabs';
31
31
  import { isObservable, firstValueFrom, BehaviorSubject, Subscription } from 'rxjs';
32
32
  import { PraxisListConfigEditor } from '@praxisui/list';
@@ -34,13 +34,13 @@ import { PraxisFilesUploadConfigEditor } from '@praxisui/files-upload';
34
34
  import { ComponentPaletteDialogComponent } from '@praxisui/page-builder';
35
35
  import * as i5 from '@angular/material/checkbox';
36
36
  import { MatCheckboxModule } from '@angular/material/checkbox';
37
- import * as i5$1 from '@angular/material/progress-spinner';
37
+ import * as i4$2 from '@angular/material/progress-spinner';
38
38
  import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
39
39
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
40
40
  import { BaseAiAdapter, shouldRoutePromptToGovernedDecision, AiBackendApiService, PraxisAssistantSessionRegistryService, PraxisAssistantTurnOrchestratorService, createPraxisAssistantViewportLayout, PraxisAiAssistantShellComponent } from '@praxisui/ai';
41
41
  import { PraxisRichContent } from '@praxisui/rich-content';
42
42
  import { take } from 'rxjs/operators';
43
- import * as i1$2 from '@angular/material/card';
43
+ import * as i1$3 from '@angular/material/card';
44
44
  import { MatCardModule } from '@angular/material/card';
45
45
 
46
46
  class SelectQuickConfigDialogComponent {
@@ -61,8 +61,8 @@ class SelectQuickConfigDialogComponent {
61
61
  }
62
62
  cancel() { this.ref.close(); }
63
63
  confirm() { this.ref.close(this.model); }
64
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: SelectQuickConfigDialogComponent, deps: [{ token: i1.MatDialogRef }, { token: MAT_DIALOG_DATA }], target: i0.ɵɵFactoryTarget.Component });
65
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.17", type: SelectQuickConfigDialogComponent, isStandalone: true, selector: "praxis-select-quick-config-dialog", ngImport: i0, template: `
64
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: SelectQuickConfigDialogComponent, deps: [{ token: i1.MatDialogRef }, { token: MAT_DIALOG_DATA }], target: i0.ɵɵFactoryTarget.Component });
65
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.14", type: SelectQuickConfigDialogComponent, isStandalone: true, selector: "praxis-select-quick-config-dialog", ngImport: i0, template: `
66
66
  <h2 mat-dialog-title>Configurar Select (busca)</h2>
67
67
  <div mat-dialog-content class="g gap-12">
68
68
  <mat-form-field appearance="outline">
@@ -96,11 +96,11 @@ class SelectQuickConfigDialogComponent {
96
96
  <button mat-button (click)="cancel()">Cancelar</button>
97
97
  <button mat-flat-button color="primary" (click)="confirm()">Adicionar</button>
98
98
  </div>
99
- `, isInline: true, styles: [".g{display:grid}.gap-12{gap:12px}.w-full{width:100%}.row{display:flex}.ai-center{align-items:center}.gap-16{gap:16px}.g-auto-220{grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i4.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: i5.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3$1.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"] }] });
99
+ `, isInline: true, styles: [".g{display:grid}.gap-12{gap:12px}.w-full{width:100%}.row{display:flex}.ai-center{align-items:center}.gap-16{gap:16px}.g-auto-220{grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.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$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i4.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: i5.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3$1.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"] }] });
100
100
  }
101
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: SelectQuickConfigDialogComponent, decorators: [{
101
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: SelectQuickConfigDialogComponent, decorators: [{
102
102
  type: Component,
103
- args: [{ selector: 'praxis-select-quick-config-dialog', standalone: true, imports: [CommonModule, FormsModule, MatDialogModule, MatFormFieldModule, MatInputModule, MatCheckboxModule, MatButtonModule], template: `
103
+ args: [{ selector: 'praxis-select-quick-config-dialog', standalone: true, imports: [FormsModule, MatDialogModule, MatFormFieldModule, MatInputModule, MatCheckboxModule, MatButtonModule], template: `
104
104
  <h2 mat-dialog-title>Configurar Select (busca)</h2>
105
105
  <div mat-dialog-content class="g gap-12">
106
106
  <mat-form-field appearance="outline">
@@ -270,8 +270,8 @@ class StepperNestedSettingsDialogComponent {
270
270
  }
271
271
  return new Set(Object.keys(declaredInputs));
272
272
  }
273
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: StepperNestedSettingsDialogComponent, deps: [{ token: MAT_DIALOG_DATA }, { token: i1.MatDialogRef }], target: i0.ɵɵFactoryTarget.Component });
274
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.17", type: StepperNestedSettingsDialogComponent, isStandalone: true, selector: "praxis-stepper-nested-settings-dialog", outputs: { applied: "applied" }, viewQueries: [{ propertyName: "contentHost", first: true, predicate: ["contentHost"], descendants: true, read: ViewContainerRef, static: true }], ngImport: i0, template: `
273
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: StepperNestedSettingsDialogComponent, deps: [{ token: MAT_DIALOG_DATA }, { token: i1.MatDialogRef }], target: i0.ɵɵFactoryTarget.Component });
274
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: StepperNestedSettingsDialogComponent, isStandalone: true, selector: "praxis-stepper-nested-settings-dialog", outputs: { applied: "applied" }, viewQueries: [{ propertyName: "contentHost", first: true, predicate: ["contentHost"], descendants: true, read: ViewContainerRef, static: true }], ngImport: i0, template: `
275
275
  <section class="pdx-stepper-nested-dialog" data-testid="stepper-nested-settings-dialog">
276
276
  <header class="pdx-stepper-nested-dialog__header">
277
277
  <div>
@@ -287,23 +287,32 @@ class StepperNestedSettingsDialogComponent {
287
287
  <mat-icon [praxisIcon]="'close'"></mat-icon>
288
288
  </button>
289
289
  </header>
290
-
290
+
291
291
  <div class="pdx-stepper-nested-dialog__status" [class.invalid]="!isValid">
292
- <mat-progress-spinner
293
- *ngIf="isBusy"
294
- diameter="18"
295
- mode="indeterminate">
296
- </mat-progress-spinner>
297
- <span *ngIf="isBusy">Operation in progress...</span>
298
- <span *ngIf="!isBusy && !isValid">Review the highlighted fields before applying.</span>
299
- <span *ngIf="!isBusy && isValid && isDirty">Ready to apply nested changes.</span>
300
- <span *ngIf="!isBusy && isValid && !isDirty">No nested changes yet.</span>
292
+ @if (isBusy) {
293
+ <mat-progress-spinner
294
+ diameter="18"
295
+ mode="indeterminate">
296
+ </mat-progress-spinner>
297
+ }
298
+ @if (isBusy) {
299
+ <span>Operation in progress...</span>
300
+ }
301
+ @if (!isBusy && !isValid) {
302
+ <span>Review the highlighted fields before applying.</span>
303
+ }
304
+ @if (!isBusy && isValid && isDirty) {
305
+ <span>Ready to apply nested changes.</span>
306
+ }
307
+ @if (!isBusy && isValid && !isDirty) {
308
+ <span>No nested changes yet.</span>
309
+ }
301
310
  </div>
302
-
311
+
303
312
  <div class="pdx-stepper-nested-dialog__body">
304
313
  <ng-container #contentHost></ng-container>
305
314
  </div>
306
-
315
+
307
316
  <footer class="pdx-stepper-nested-dialog__footer">
308
317
  <button
309
318
  mat-button
@@ -333,17 +342,16 @@ class StepperNestedSettingsDialogComponent {
333
342
  </button>
334
343
  </footer>
335
344
  </section>
336
- `, isInline: true, styles: [":host{display:block}.pdx-stepper-nested-dialog{--pdx-nested-surface: color-mix(in srgb, var(--md-sys-color-surface-container, #1f2630) 92%, black);background:var(--pdx-nested-surface);color:var(--md-sys-color-on-surface, #eef2ff);min-width:min(760px,88vw);max-width:92vw;max-height:86vh;display:grid;grid-template-rows:auto auto minmax(0,1fr) auto;overflow:hidden}.pdx-stepper-nested-dialog__header,.pdx-stepper-nested-dialog__footer{display:flex;align-items:center;gap:12px;padding:16px 20px;border-color:color-mix(in srgb,var(--md-sys-color-outline-variant, #4b5563) 48%,transparent)}.pdx-stepper-nested-dialog__header{justify-content:space-between;border-bottom:1px solid}.pdx-stepper-nested-dialog__header h2{margin:0;font-size:18px;font-weight:800;letter-spacing:-.01em}.pdx-stepper-nested-dialog__eyebrow{margin:0 0 4px;color:var(--md-sys-color-primary, #8ab4ff);font-size:12px;font-weight:800;letter-spacing:.06em;text-transform:uppercase}.pdx-stepper-nested-dialog__status{min-height:34px;display:flex;align-items:center;gap:8px;padding:8px 20px;color:var(--md-sys-color-on-surface-variant, #c7d2fe);background:color-mix(in srgb,var(--md-sys-color-primary-container, #1d3a5f) 18%,transparent);font-size:12px}.pdx-stepper-nested-dialog__status.invalid{color:var(--md-sys-color-error, #ffb4ab);background:color-mix(in srgb,var(--md-sys-color-error-container, #5f1b1b) 18%,transparent)}.pdx-stepper-nested-dialog__body{min-height:0;overflow:auto;padding:16px 20px 22px}.pdx-stepper-nested-dialog__footer{border-top:1px solid}.pdx-stepper-nested-dialog__spacer{flex:1 1 auto}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3$1.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$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: MatIconModule }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i5$1.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
345
+ `, isInline: true, styles: [":host{display:block}.pdx-stepper-nested-dialog{--pdx-nested-surface: color-mix(in srgb, var(--md-sys-color-surface-container, #1f2630) 92%, black);background:var(--pdx-nested-surface);color:var(--md-sys-color-on-surface, #eef2ff);min-width:min(760px,88vw);max-width:92vw;max-height:86vh;display:grid;grid-template-rows:auto auto minmax(0,1fr) auto;overflow:hidden}.pdx-stepper-nested-dialog__header,.pdx-stepper-nested-dialog__footer{display:flex;align-items:center;gap:12px;padding:16px 20px;border-color:color-mix(in srgb,var(--md-sys-color-outline-variant, #4b5563) 48%,transparent)}.pdx-stepper-nested-dialog__header{justify-content:space-between;border-bottom:1px solid}.pdx-stepper-nested-dialog__header h2{margin:0;font-size:18px;font-weight:800;letter-spacing:-.01em}.pdx-stepper-nested-dialog__eyebrow{margin:0 0 4px;color:var(--md-sys-color-primary, #8ab4ff);font-size:12px;font-weight:800;letter-spacing:.06em;text-transform:uppercase}.pdx-stepper-nested-dialog__status{min-height:34px;display:flex;align-items:center;gap:8px;padding:8px 20px;color:var(--md-sys-color-on-surface-variant, #c7d2fe);background:color-mix(in srgb,var(--md-sys-color-primary-container, #1d3a5f) 18%,transparent);font-size:12px}.pdx-stepper-nested-dialog__status.invalid{color:var(--md-sys-color-error, #ffb4ab);background:color-mix(in srgb,var(--md-sys-color-error-container, #5f1b1b) 18%,transparent)}.pdx-stepper-nested-dialog__body{min-height:0;overflow:auto;padding:16px 20px 22px}.pdx-stepper-nested-dialog__footer{border-top:1px solid}.pdx-stepper-nested-dialog__spacer{flex:1 1 auto}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3$1.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$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: MatIconModule }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i4$2.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
337
346
  }
338
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: StepperNestedSettingsDialogComponent, decorators: [{
347
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: StepperNestedSettingsDialogComponent, decorators: [{
339
348
  type: Component,
340
349
  args: [{ selector: 'praxis-stepper-nested-settings-dialog', standalone: true, imports: [
341
- CommonModule,
342
350
  MatButtonModule,
343
351
  MatDialogModule,
344
352
  MatIconModule,
345
353
  MatProgressSpinnerModule,
346
- PraxisIconDirective,
354
+ PraxisIconDirective
347
355
  ], template: `
348
356
  <section class="pdx-stepper-nested-dialog" data-testid="stepper-nested-settings-dialog">
349
357
  <header class="pdx-stepper-nested-dialog__header">
@@ -360,23 +368,32 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
360
368
  <mat-icon [praxisIcon]="'close'"></mat-icon>
361
369
  </button>
362
370
  </header>
363
-
371
+
364
372
  <div class="pdx-stepper-nested-dialog__status" [class.invalid]="!isValid">
365
- <mat-progress-spinner
366
- *ngIf="isBusy"
367
- diameter="18"
368
- mode="indeterminate">
369
- </mat-progress-spinner>
370
- <span *ngIf="isBusy">Operation in progress...</span>
371
- <span *ngIf="!isBusy && !isValid">Review the highlighted fields before applying.</span>
372
- <span *ngIf="!isBusy && isValid && isDirty">Ready to apply nested changes.</span>
373
- <span *ngIf="!isBusy && isValid && !isDirty">No nested changes yet.</span>
373
+ @if (isBusy) {
374
+ <mat-progress-spinner
375
+ diameter="18"
376
+ mode="indeterminate">
377
+ </mat-progress-spinner>
378
+ }
379
+ @if (isBusy) {
380
+ <span>Operation in progress...</span>
381
+ }
382
+ @if (!isBusy && !isValid) {
383
+ <span>Review the highlighted fields before applying.</span>
384
+ }
385
+ @if (!isBusy && isValid && isDirty) {
386
+ <span>Ready to apply nested changes.</span>
387
+ }
388
+ @if (!isBusy && isValid && !isDirty) {
389
+ <span>No nested changes yet.</span>
390
+ }
374
391
  </div>
375
-
392
+
376
393
  <div class="pdx-stepper-nested-dialog__body">
377
394
  <ng-container #contentHost></ng-container>
378
395
  </div>
379
-
396
+
380
397
  <footer class="pdx-stepper-nested-dialog__footer">
381
398
  <button
382
399
  mat-button
@@ -406,7 +423,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
406
423
  </button>
407
424
  </footer>
408
425
  </section>
409
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block}.pdx-stepper-nested-dialog{--pdx-nested-surface: color-mix(in srgb, var(--md-sys-color-surface-container, #1f2630) 92%, black);background:var(--pdx-nested-surface);color:var(--md-sys-color-on-surface, #eef2ff);min-width:min(760px,88vw);max-width:92vw;max-height:86vh;display:grid;grid-template-rows:auto auto minmax(0,1fr) auto;overflow:hidden}.pdx-stepper-nested-dialog__header,.pdx-stepper-nested-dialog__footer{display:flex;align-items:center;gap:12px;padding:16px 20px;border-color:color-mix(in srgb,var(--md-sys-color-outline-variant, #4b5563) 48%,transparent)}.pdx-stepper-nested-dialog__header{justify-content:space-between;border-bottom:1px solid}.pdx-stepper-nested-dialog__header h2{margin:0;font-size:18px;font-weight:800;letter-spacing:-.01em}.pdx-stepper-nested-dialog__eyebrow{margin:0 0 4px;color:var(--md-sys-color-primary, #8ab4ff);font-size:12px;font-weight:800;letter-spacing:.06em;text-transform:uppercase}.pdx-stepper-nested-dialog__status{min-height:34px;display:flex;align-items:center;gap:8px;padding:8px 20px;color:var(--md-sys-color-on-surface-variant, #c7d2fe);background:color-mix(in srgb,var(--md-sys-color-primary-container, #1d3a5f) 18%,transparent);font-size:12px}.pdx-stepper-nested-dialog__status.invalid{color:var(--md-sys-color-error, #ffb4ab);background:color-mix(in srgb,var(--md-sys-color-error-container, #5f1b1b) 18%,transparent)}.pdx-stepper-nested-dialog__body{min-height:0;overflow:auto;padding:16px 20px 22px}.pdx-stepper-nested-dialog__footer{border-top:1px solid}.pdx-stepper-nested-dialog__spacer{flex:1 1 auto}\n"] }]
426
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block}.pdx-stepper-nested-dialog{--pdx-nested-surface: color-mix(in srgb, var(--md-sys-color-surface-container, #1f2630) 92%, black);background:var(--pdx-nested-surface);color:var(--md-sys-color-on-surface, #eef2ff);min-width:min(760px,88vw);max-width:92vw;max-height:86vh;display:grid;grid-template-rows:auto auto minmax(0,1fr) auto;overflow:hidden}.pdx-stepper-nested-dialog__header,.pdx-stepper-nested-dialog__footer{display:flex;align-items:center;gap:12px;padding:16px 20px;border-color:color-mix(in srgb,var(--md-sys-color-outline-variant, #4b5563) 48%,transparent)}.pdx-stepper-nested-dialog__header{justify-content:space-between;border-bottom:1px solid}.pdx-stepper-nested-dialog__header h2{margin:0;font-size:18px;font-weight:800;letter-spacing:-.01em}.pdx-stepper-nested-dialog__eyebrow{margin:0 0 4px;color:var(--md-sys-color-primary, #8ab4ff);font-size:12px;font-weight:800;letter-spacing:.06em;text-transform:uppercase}.pdx-stepper-nested-dialog__status{min-height:34px;display:flex;align-items:center;gap:8px;padding:8px 20px;color:var(--md-sys-color-on-surface-variant, #c7d2fe);background:color-mix(in srgb,var(--md-sys-color-primary-container, #1d3a5f) 18%,transparent);font-size:12px}.pdx-stepper-nested-dialog__status.invalid{color:var(--md-sys-color-error, #ffb4ab);background:color-mix(in srgb,var(--md-sys-color-error-container, #5f1b1b) 18%,transparent)}.pdx-stepper-nested-dialog__body{min-height:0;overflow:auto;padding:16px 20px 22px}.pdx-stepper-nested-dialog__footer{border-top:1px solid}.pdx-stepper-nested-dialog__spacer{flex:1 1 auto}\n"] }]
410
427
  }], ctorParameters: () => [{ type: undefined, decorators: [{
411
428
  type: Inject,
412
429
  args: [MAT_DIALOG_DATA]
@@ -1548,8 +1565,8 @@ class PraxisStepperConfigEditor {
1548
1565
  this.isBusy$.next(false);
1549
1566
  }
1550
1567
  }
1551
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisStepperConfigEditor, deps: [{ token: SETTINGS_PANEL_DATA }], target: i0.ɵɵFactoryTarget.Component });
1552
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.17", type: PraxisStepperConfigEditor, isStandalone: true, selector: "praxis-stepper-config-editor", inputs: { stepperConfig: "stepperConfig" }, providers: [providePraxisStepperI18n()], ngImport: i0, template: `
1568
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisStepperConfigEditor, deps: [{ token: SETTINGS_PANEL_DATA }], target: i0.ɵɵFactoryTarget.Component });
1569
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PraxisStepperConfigEditor, isStandalone: true, selector: "praxis-stepper-config-editor", inputs: { stepperConfig: "stepperConfig" }, providers: [providePraxisStepperI18n()], ngImport: i0, template: `
1553
1570
  <div class="pdx-editor">
1554
1571
  <mat-tab-group>
1555
1572
  <mat-tab [label]="tx('editor.tabs.general', 'General')">
@@ -1632,7 +1649,7 @@ class PraxisStepperConfigEditor {
1632
1649
  </details>
1633
1650
  </div>
1634
1651
  </mat-tab>
1635
-
1652
+
1636
1653
  <mat-tab [label]="tx('editor.tabs.steps', 'Steps')">
1637
1654
  <div class="tab-pad">
1638
1655
  <div class="editor-intro">
@@ -1656,295 +1673,299 @@ class PraxisStepperConfigEditor {
1656
1673
  </div>
1657
1674
  <button mat-flat-button color="primary" (click)="addStep()"><mat-icon [praxisIcon]="'add'"></mat-icon>{{ tx('editor.steps.add', 'Add step') }}</button>
1658
1675
  </div>
1659
- <div class="steps-workspace" *ngIf="activeStep as step; else noSteps">
1660
- <div
1661
- cdkDropList
1662
- role="listbox"
1663
- [attr.aria-label]="tx('editor.steps.listAria', 'Step list')"
1664
- (cdkDropListDropped)="drop($event)"
1665
- class="pdx-step-list">
1676
+ @if (activeStep; as step) {
1677
+ <div class="steps-workspace">
1666
1678
  <div
1667
- class="pdx-step-item"
1668
- *ngFor="let s of config.steps; let i = index"
1669
- cdkDrag
1670
- role="option"
1671
- [attr.aria-selected]="activeStep === s"
1672
- [attr.tabindex]="activeStep === s ? 0 : -1"
1673
- [class.active]="activeStep === s"
1674
- (click)="setActive(s)"
1675
- (keydown.enter)="onStepItemEnter($event, s)"
1676
- (keydown.space)="onStepItemSpace($event, s)"
1677
- (keydown.arrowdown)="focusAdjacentStep($event, i, 1)"
1678
- (keydown.arrowup)="focusAdjacentStep($event, i, -1)">
1679
- <div class="drag-handle" cdkDragHandle><mat-icon [praxisIcon]="'drag_indicator'"></mat-icon></div>
1680
- <div class="step-summary">
1681
- <div class="step-summary-head">
1682
- <div class="step-summary-index">{{ stepIndexLabel(i) }}</div>
1683
- <div class="step-summary-title">{{ s.label || tx('editor.steps.untitled', 'Untitled') }}</div>
1684
- </div>
1685
- <div class="step-summary-sub">{{ s.id || tx('editor.steps.noId', 'No identifier') }}</div>
1686
- <div class="step-summary-flags">
1687
- <span class="summary-chip" *ngIf="s.optional">{{ tx('editor.steps.optional', 'Optional') }}</span>
1688
- <span class="summary-chip" *ngIf="s.completed">{{ tx('editor.steps.completed', 'Completed') }}</span>
1689
- <span class="summary-chip summary-chip-warn" *ngIf="s.hasError">{{ tx('editor.steps.error', 'Error') }}</span>
1690
- <span class="summary-chip" *ngIf="s.form">{{ tx('editor.steps.form', 'Form') }}</span>
1691
- </div>
1692
- </div>
1693
- <div class="pdx-actions">
1694
- <button mat-icon-button color="warn" (click)="removeStep(i); $event.stopPropagation()" [matTooltip]="tx('editor.steps.remove', 'Remove')" [attr.aria-label]="stepRemoveAria(s, i)">
1695
- <mat-icon [praxisIcon]="'delete'"></mat-icon>
1696
- </button>
1697
- </div>
1698
- </div>
1699
- </div>
1700
-
1701
- <div class="pdx-active-step">
1702
- <div class="hdr">
1703
- <div class="active-step-head">
1704
- <div class="eyebrow">{{ tx('editor.steps.selectedEyebrow', 'Selected step') }}</div>
1705
- <div class="title">{{ editingStepTitle(step) }}</div>
1706
- <div class="section-subtitle">{{ tx('editor.steps.selectedSubtitle', 'Adjust the main content first. Secondary settings stay collapsed to reduce noise.') }}</div>
1707
- </div>
1708
- </div>
1709
-
1710
- <div class="section">
1711
- <div class="section-title">{{ tx('editor.steps.mainData', 'Main data') }}</div>
1712
- <div class="detail-grid">
1713
- <mat-form-field appearance="outline" class="field-span-2">
1714
- <mat-label>{{ tx('editor.steps.stepTitle', 'Step title') }}</mat-label>
1715
- <input matInput [(ngModel)]="step.label" (ngModelChange)="markDirty()" />
1716
- </mat-form-field>
1717
- <mat-form-field appearance="outline">
1718
- <mat-label>{{ tx('editor.steps.identifier', 'Identifier') }}</mat-label>
1719
- <input matInput [(ngModel)]="step.id" (ngModelChange)="markDirty()" />
1720
- </mat-form-field>
1721
- <mat-form-field appearance="outline">
1722
- <mat-label>{{ tx('editor.steps.iconOrState', 'Icon or state') }}</mat-label>
1723
- <input matInput [(ngModel)]="step.state" (ngModelChange)="markDirty()" [placeholder]="tx('editor.steps.iconOrStatePlaceholder', 'e.g.: number, done, edit')" />
1724
- </mat-form-field>
1725
- <mat-form-field appearance="outline" class="field-span-2">
1726
- <mat-label>{{ tx('editor.steps.errorMessage', 'Error message') }}</mat-label>
1727
- <input matInput [(ngModel)]="step.errorMessage" (ngModelChange)="markDirty()" />
1728
- </mat-form-field>
1729
- </div>
1730
- <div class="toggle-group">
1731
- <mat-slide-toggle [(ngModel)]="step.optional" (ngModelChange)="markDirty()">{{ tx('editor.steps.optionalToggle', 'Optional step') }}</mat-slide-toggle>
1732
- <mat-slide-toggle [(ngModel)]="step.editable" (ngModelChange)="markDirty()">{{ tx('editor.steps.editableToggle', 'Allow going back and editing') }}</mat-slide-toggle>
1733
- <mat-slide-toggle [(ngModel)]="step.completed" (ngModelChange)="markDirty()">{{ tx('editor.steps.completedToggle', 'Mark as completed') }}</mat-slide-toggle>
1734
- <mat-slide-toggle [(ngModel)]="step.hasError" (ngModelChange)="markDirty()">{{ tx('editor.steps.errorToggle', 'Mark as error') }}</mat-slide-toggle>
1735
- </div>
1736
- </div>
1737
-
1738
- <details class="disclosure">
1739
- <summary>
1740
- <span class="section-title">{{ tx('editor.steps.accessibilityTitle', 'Accessibility and technical details') }}</span>
1741
- <span class="section-subtitle">{{ tx('editor.steps.accessibilitySubtitle', 'Auxiliary labels and less-used metadata.') }}</span>
1742
- </summary>
1743
- <div class="detail-grid disclosure-body">
1744
- <mat-form-field appearance="outline">
1745
- <mat-label>{{ tx('editor.steps.altText', 'Alternative text') }}</mat-label>
1746
- <input matInput [(ngModel)]="step.ariaLabel" (ngModelChange)="markDirty()" />
1747
- </mat-form-field>
1748
- <mat-form-field appearance="outline">
1749
- <mat-label>{{ tx('editor.steps.describedBy', 'Described-by ID') }}</mat-label>
1750
- <input matInput [(ngModel)]="step.ariaLabelledby" (ngModelChange)="markDirty()" />
1751
- </mat-form-field>
1752
- </div>
1753
- </details>
1754
-
1755
- <div class="pdx-content-editor">
1756
- <div class="section editorial-section">
1757
- <div class="section-head">
1758
- <div>
1759
- <div class="section-title">{{ tx('editor.steps.editorialTitle', 'Editorial content') }}</div>
1760
- <div class="section-subtitle">{{ tx('editor.steps.editorialSubtitle', 'Use supporting blocks to contextualize the step before or after the form.') }}</div>
1761
- </div>
1762
- </div>
1763
-
1764
- <div class="zone-grid">
1765
- <div class="zone-column">
1766
- <div class="zone-head">
1767
- <div class="zone-title">{{ tx('editor.steps.zoneBefore', 'Before form') }}</div>
1768
- <div class="zone-actions">
1769
- <span class="zone-count">{{ richContentNodeCount(step.stepBlocksBeforeForm) }}</span>
1770
- <button mat-stroked-button type="button" (click)="seedRichContent(step, 'before')">
1771
- <mat-icon [praxisIcon]="'auto_awesome'"></mat-icon>
1772
- {{ tx('editor.steps.seedRichContent', 'Seed') }}
1773
- </button>
1679
+ cdkDropList
1680
+ role="listbox"
1681
+ [attr.aria-label]="tx('editor.steps.listAria', 'Step list')"
1682
+ (cdkDropListDropped)="drop($event)"
1683
+ class="pdx-step-list">
1684
+ @for (s of config.steps; track s; let i = $index) {
1685
+ <div
1686
+ class="pdx-step-item"
1687
+ cdkDrag
1688
+ role="option"
1689
+ [attr.aria-selected]="activeStep === s"
1690
+ [attr.tabindex]="activeStep === s ? 0 : -1"
1691
+ [class.active]="activeStep === s"
1692
+ (click)="setActive(s)"
1693
+ (keydown.enter)="onStepItemEnter($event, s)"
1694
+ (keydown.space)="onStepItemSpace($event, s)"
1695
+ (keydown.arrowdown)="focusAdjacentStep($event, i, 1)"
1696
+ (keydown.arrowup)="focusAdjacentStep($event, i, -1)">
1697
+ <div class="drag-handle" cdkDragHandle><mat-icon [praxisIcon]="'drag_indicator'"></mat-icon></div>
1698
+ <div class="step-summary">
1699
+ <div class="step-summary-head">
1700
+ <div class="step-summary-index">{{ stepIndexLabel(i) }}</div>
1701
+ <div class="step-summary-title">{{ s.label || tx('editor.steps.untitled', 'Untitled') }}</div>
1702
+ </div>
1703
+ <div class="step-summary-sub">{{ s.id || tx('editor.steps.noId', 'No identifier') }}</div>
1704
+ <div class="step-summary-flags">
1705
+ @if (s.optional) {
1706
+ <span class="summary-chip">{{ tx('editor.steps.optional', 'Optional') }}</span>
1707
+ }
1708
+ @if (s.completed) {
1709
+ <span class="summary-chip">{{ tx('editor.steps.completed', 'Completed') }}</span>
1710
+ }
1711
+ @if (s.hasError) {
1712
+ <span class="summary-chip summary-chip-warn">{{ tx('editor.steps.error', 'Error') }}</span>
1713
+ }
1714
+ @if (s.form) {
1715
+ <span class="summary-chip">{{ tx('editor.steps.form', 'Form') }}</span>
1716
+ }
1717
+ </div>
1774
1718
  </div>
1775
- </div>
1776
- <mat-form-field appearance="outline" class="w-full rich-content-json">
1777
- <mat-label>{{ tx('editor.steps.richContentDocument', 'RichContentDocument JSON') }}</mat-label>
1778
- <textarea
1779
- matInput
1780
- rows="12"
1781
- [ngModel]="richContentJson(step, 'before')"
1782
- (ngModelChange)="setRichContentJson(step, 'before', $event)"
1783
- ></textarea>
1784
- </mat-form-field>
1785
- <button mat-button color="warn" type="button" (click)="clearRichContent(step, 'before')">
1786
- <mat-icon [praxisIcon]="'delete'"></mat-icon>
1787
- {{ tx('editor.steps.clearZone', 'Clear zone') }}
1788
- </button>
1789
- </div>
1790
-
1791
- <div class="zone-column">
1792
- <div class="zone-head">
1793
- <div class="zone-title">{{ tx('editor.steps.zoneAfter', 'After form') }}</div>
1794
- <div class="zone-actions">
1795
- <span class="zone-count">{{ richContentNodeCount(step.stepBlocksAfterForm) }}</span>
1796
- <button mat-stroked-button type="button" (click)="seedRichContent(step, 'after')">
1797
- <mat-icon [praxisIcon]="'auto_awesome'"></mat-icon>
1798
- {{ tx('editor.steps.seedRichContent', 'Seed') }}
1719
+ <div class="pdx-actions">
1720
+ <button mat-icon-button color="warn" (click)="removeStep(i); $event.stopPropagation()" [matTooltip]="tx('editor.steps.remove', 'Remove')" [attr.aria-label]="stepRemoveAria(s, i)">
1721
+ <mat-icon [praxisIcon]="'delete'"></mat-icon>
1799
1722
  </button>
1800
1723
  </div>
1801
1724
  </div>
1802
- <mat-form-field appearance="outline" class="w-full rich-content-json">
1803
- <mat-label>{{ tx('editor.steps.richContentDocument', 'RichContentDocument JSON') }}</mat-label>
1804
- <textarea
1805
- matInput
1806
- rows="12"
1807
- [ngModel]="richContentJson(step, 'after')"
1808
- (ngModelChange)="setRichContentJson(step, 'after', $event)"
1809
- ></textarea>
1810
- </mat-form-field>
1811
- <button mat-button color="warn" type="button" (click)="clearRichContent(step, 'after')">
1812
- <mat-icon [praxisIcon]="'delete'"></mat-icon>
1813
- {{ tx('editor.steps.clearZone', 'Clear zone') }}
1814
- </button>
1815
- </div>
1725
+ }
1816
1726
  </div>
1817
- </div>
1818
-
1819
- <div class="section">
1820
- <div class="section-title">{{ tx('editor.steps.formSectionTitle', 'Step form') }}</div>
1821
- <div class="section-body">
1822
- <ng-container *ngIf="step.form; else addFormBtn">
1823
- <div class="form-row-card">
1824
- <div class="form-row-main">
1825
- <mat-icon [praxisIcon]="'dynamic_form'"></mat-icon>
1826
- <div>
1827
- <div class="name">{{ tx('editor.steps.mainFormTitle', 'Main form') }}</div>
1828
- <div class="sub">{{ step.form.formId || step.id || '—' }}</div>
1829
- </div>
1830
- </div>
1831
- <div class="form-row-actions">
1832
- <button mat-button (click)="editMainForm()"><mat-icon [praxisIcon]="'tune'"></mat-icon>{{ tx('editor.steps.edit', 'Edit') }}</button>
1833
- <button mat-button color="warn" (click)="removeMainForm()"><mat-icon [praxisIcon]="'delete'"></mat-icon>{{ tx('editor.steps.remove', 'Remove') }}</button>
1834
- </div>
1727
+ <div class="pdx-active-step">
1728
+ <div class="hdr">
1729
+ <div class="active-step-head">
1730
+ <div class="eyebrow">{{ tx('editor.steps.selectedEyebrow', 'Selected step') }}</div>
1731
+ <div class="title">{{ editingStepTitle(step) }}</div>
1732
+ <div class="section-subtitle">{{ tx('editor.steps.selectedSubtitle', 'Adjust the main content first. Secondary settings stay collapsed to reduce noise.') }}</div>
1835
1733
  </div>
1836
- </ng-container>
1837
- <ng-template #addFormBtn>
1838
- <button mat-stroked-button color="primary" (click)="addMainForm()"><mat-icon [praxisIcon]="'add'"></mat-icon>{{ tx('editor.steps.addForm', 'Add form') }}</button>
1839
- </ng-template>
1840
- </div>
1841
- </div>
1842
-
1843
- <div class="section">
1844
- <div class="section-head">
1845
- <div>
1846
- <div class="section-title">{{ tx('editor.steps.advancedTitle', 'Advanced components') }}</div>
1847
- <div class="section-subtitle">{{ tx('editor.steps.advancedSubtitle', 'Shortcuts to assemble richer experiences without losing clarity in the flow.') }}</div>
1848
1734
  </div>
1849
- <button mat-stroked-button (click)="openMoreComponents()">
1850
- <mat-icon [praxisIcon]="'add'"></mat-icon>
1851
- {{ tx('editor.steps.moreComponents', 'More components') }}
1852
- </button>
1853
- </div>
1854
- <div class="section-body">
1855
- <div class="cta-grid">
1856
- <div class="cta-row-item">
1857
- <div class="cta-head">
1858
- <mat-icon [praxisIcon]="'account_tree'"></mat-icon>
1859
- <div>
1860
- <div class="cta-title">{{ tx('editor.steps.treeListTitle', 'Tree list') }}</div>
1861
- <div class="cta-desc">{{ tx('editor.steps.treeListDesc', 'Hierarchical data with simple selection.') }}</div>
1862
- </div>
1863
- </div>
1864
- <div class="cta-actions">
1865
- <button mat-stroked-button (click)="addTreeList()">
1866
- <mat-icon [praxisIcon]="'add'"></mat-icon>
1867
- {{ tx('editor.steps.insertTree', 'Insert tree') }}
1868
- </button>
1869
- </div>
1735
+ <div class="section">
1736
+ <div class="section-title">{{ tx('editor.steps.mainData', 'Main data') }}</div>
1737
+ <div class="detail-grid">
1738
+ <mat-form-field appearance="outline" class="field-span-2">
1739
+ <mat-label>{{ tx('editor.steps.stepTitle', 'Step title') }}</mat-label>
1740
+ <input matInput [(ngModel)]="step.label" (ngModelChange)="markDirty()" />
1741
+ </mat-form-field>
1742
+ <mat-form-field appearance="outline">
1743
+ <mat-label>{{ tx('editor.steps.identifier', 'Identifier') }}</mat-label>
1744
+ <input matInput [(ngModel)]="step.id" (ngModelChange)="markDirty()" />
1745
+ </mat-form-field>
1746
+ <mat-form-field appearance="outline">
1747
+ <mat-label>{{ tx('editor.steps.iconOrState', 'Icon or state') }}</mat-label>
1748
+ <input matInput [(ngModel)]="step.state" (ngModelChange)="markDirty()" [placeholder]="tx('editor.steps.iconOrStatePlaceholder', 'e.g.: number, done, edit')" />
1749
+ </mat-form-field>
1750
+ <mat-form-field appearance="outline" class="field-span-2">
1751
+ <mat-label>{{ tx('editor.steps.errorMessage', 'Error message') }}</mat-label>
1752
+ <input matInput [(ngModel)]="step.errorMessage" (ngModelChange)="markDirty()" />
1753
+ </mat-form-field>
1870
1754
  </div>
1871
- <div class="cta-row-item">
1872
- <div class="cta-head">
1873
- <mat-icon [praxisIcon]="'swap_horiz'"></mat-icon>
1755
+ <div class="toggle-group">
1756
+ <mat-slide-toggle [(ngModel)]="step.optional" (ngModelChange)="markDirty()">{{ tx('editor.steps.optionalToggle', 'Optional step') }}</mat-slide-toggle>
1757
+ <mat-slide-toggle [(ngModel)]="step.editable" (ngModelChange)="markDirty()">{{ tx('editor.steps.editableToggle', 'Allow going back and editing') }}</mat-slide-toggle>
1758
+ <mat-slide-toggle [(ngModel)]="step.completed" (ngModelChange)="markDirty()">{{ tx('editor.steps.completedToggle', 'Mark as completed') }}</mat-slide-toggle>
1759
+ <mat-slide-toggle [(ngModel)]="step.hasError" (ngModelChange)="markDirty()">{{ tx('editor.steps.errorToggle', 'Mark as error') }}</mat-slide-toggle>
1760
+ </div>
1761
+ </div>
1762
+ <details class="disclosure">
1763
+ <summary>
1764
+ <span class="section-title">{{ tx('editor.steps.accessibilityTitle', 'Accessibility and technical details') }}</span>
1765
+ <span class="section-subtitle">{{ tx('editor.steps.accessibilitySubtitle', 'Auxiliary labels and less-used metadata.') }}</span>
1766
+ </summary>
1767
+ <div class="detail-grid disclosure-body">
1768
+ <mat-form-field appearance="outline">
1769
+ <mat-label>{{ tx('editor.steps.altText', 'Alternative text') }}</mat-label>
1770
+ <input matInput [(ngModel)]="step.ariaLabel" (ngModelChange)="markDirty()" />
1771
+ </mat-form-field>
1772
+ <mat-form-field appearance="outline">
1773
+ <mat-label>{{ tx('editor.steps.describedBy', 'Described-by ID') }}</mat-label>
1774
+ <input matInput [(ngModel)]="step.ariaLabelledby" (ngModelChange)="markDirty()" />
1775
+ </mat-form-field>
1776
+ </div>
1777
+ </details>
1778
+ <div class="pdx-content-editor">
1779
+ <div class="section editorial-section">
1780
+ <div class="section-head">
1874
1781
  <div>
1875
- <div class="cta-title">{{ tx('editor.steps.transferTitle', 'Item transfer') }}</div>
1876
- <div class="cta-desc">{{ tx('editor.steps.transferDesc', 'Move items between lists for multi-selection.') }}</div>
1782
+ <div class="section-title">{{ tx('editor.steps.editorialTitle', 'Editorial content') }}</div>
1783
+ <div class="section-subtitle">{{ tx('editor.steps.editorialSubtitle', 'Use supporting blocks to contextualize the step before or after the form.') }}</div>
1877
1784
  </div>
1878
1785
  </div>
1879
- <div class="cta-actions">
1880
- <button mat-stroked-button (click)="addTransferListQuick()">
1881
- <mat-icon [praxisIcon]="'add'"></mat-icon>
1882
- {{ tx('editor.steps.insertTransfer', 'Insert transfer') }}
1883
- </button>
1884
- </div>
1885
- </div>
1886
- <div class="cta-row-item">
1887
- <div class="cta-head">
1888
- <mat-icon [praxisIcon]="'search'"></mat-icon>
1889
- <div>
1890
- <div class="cta-title">{{ tx('editor.steps.searchTitle', 'Searchable selection') }}</div>
1891
- <div class="cta-desc">{{ tx('editor.steps.searchDesc', 'Selection with local or remote search.') }}</div>
1786
+ <div class="zone-grid">
1787
+ <div class="zone-column">
1788
+ <div class="zone-head">
1789
+ <div class="zone-title">{{ tx('editor.steps.zoneBefore', 'Before form') }}</div>
1790
+ <div class="zone-actions">
1791
+ <span class="zone-count">{{ richContentNodeCount(step.stepBlocksBeforeForm) }}</span>
1792
+ <button mat-stroked-button type="button" (click)="seedRichContent(step, 'before')">
1793
+ <mat-icon [praxisIcon]="'auto_awesome'"></mat-icon>
1794
+ {{ tx('editor.steps.seedRichContent', 'Seed') }}
1795
+ </button>
1796
+ </div>
1797
+ </div>
1798
+ <mat-form-field appearance="outline" class="w-full rich-content-json">
1799
+ <mat-label>{{ tx('editor.steps.richContentDocument', 'RichContentDocument JSON') }}</mat-label>
1800
+ <textarea
1801
+ matInput
1802
+ rows="12"
1803
+ [ngModel]="richContentJson(step, 'before')"
1804
+ (ngModelChange)="setRichContentJson(step, 'before', $event)"
1805
+ ></textarea>
1806
+ </mat-form-field>
1807
+ <button mat-button color="warn" type="button" (click)="clearRichContent(step, 'before')">
1808
+ <mat-icon [praxisIcon]="'delete'"></mat-icon>
1809
+ {{ tx('editor.steps.clearZone', 'Clear zone') }}
1810
+ </button>
1811
+ </div>
1812
+ <div class="zone-column">
1813
+ <div class="zone-head">
1814
+ <div class="zone-title">{{ tx('editor.steps.zoneAfter', 'After form') }}</div>
1815
+ <div class="zone-actions">
1816
+ <span class="zone-count">{{ richContentNodeCount(step.stepBlocksAfterForm) }}</span>
1817
+ <button mat-stroked-button type="button" (click)="seedRichContent(step, 'after')">
1818
+ <mat-icon [praxisIcon]="'auto_awesome'"></mat-icon>
1819
+ {{ tx('editor.steps.seedRichContent', 'Seed') }}
1820
+ </button>
1821
+ </div>
1822
+ </div>
1823
+ <mat-form-field appearance="outline" class="w-full rich-content-json">
1824
+ <mat-label>{{ tx('editor.steps.richContentDocument', 'RichContentDocument JSON') }}</mat-label>
1825
+ <textarea
1826
+ matInput
1827
+ rows="12"
1828
+ [ngModel]="richContentJson(step, 'after')"
1829
+ (ngModelChange)="setRichContentJson(step, 'after', $event)"
1830
+ ></textarea>
1831
+ </mat-form-field>
1832
+ <button mat-button color="warn" type="button" (click)="clearRichContent(step, 'after')">
1833
+ <mat-icon [praxisIcon]="'delete'"></mat-icon>
1834
+ {{ tx('editor.steps.clearZone', 'Clear zone') }}
1835
+ </button>
1892
1836
  </div>
1893
1837
  </div>
1894
- <div class="cta-actions">
1895
- <button mat-stroked-button (click)="addSearchableSelect()">
1896
- <mat-icon [praxisIcon]="'add'"></mat-icon>
1897
- {{ tx('editor.steps.insertSelector', 'Insert selector') }}
1898
- </button>
1838
+ </div>
1839
+ <div class="section">
1840
+ <div class="section-title">{{ tx('editor.steps.formSectionTitle', 'Step form') }}</div>
1841
+ <div class="section-body">
1842
+ @if (step.form) {
1843
+ <div class="form-row-card">
1844
+ <div class="form-row-main">
1845
+ <mat-icon [praxisIcon]="'dynamic_form'"></mat-icon>
1846
+ <div>
1847
+ <div class="name">{{ tx('editor.steps.mainFormTitle', 'Main form') }}</div>
1848
+ <div class="sub">{{ step.form.formId || step.id || '—' }}</div>
1849
+ </div>
1850
+ </div>
1851
+ <div class="form-row-actions">
1852
+ <button mat-button (click)="editMainForm()"><mat-icon [praxisIcon]="'tune'"></mat-icon>{{ tx('editor.steps.edit', 'Edit') }}</button>
1853
+ <button mat-button color="warn" (click)="removeMainForm()"><mat-icon [praxisIcon]="'delete'"></mat-icon>{{ tx('editor.steps.remove', 'Remove') }}</button>
1854
+ </div>
1855
+ </div>
1856
+ } @else {
1857
+ <button mat-stroked-button color="primary" (click)="addMainForm()"><mat-icon [praxisIcon]="'add'"></mat-icon>{{ tx('editor.steps.addForm', 'Add form') }}</button>
1858
+ }
1899
1859
  </div>
1900
1860
  </div>
1901
- <div class="cta-row-item">
1902
- <div class="cta-head">
1903
- <mat-icon [praxisIcon]="'upload_file'"></mat-icon>
1861
+ <div class="section">
1862
+ <div class="section-head">
1904
1863
  <div>
1905
- <div class="cta-title">{{ tx('editor.steps.uploadTitle', 'File upload') }}</div>
1906
- <div class="cta-desc">{{ tx('editor.steps.uploadDesc', 'Attachments with validation and upload flow.') }}</div>
1864
+ <div class="section-title">{{ tx('editor.steps.advancedTitle', 'Advanced components') }}</div>
1865
+ <div class="section-subtitle">{{ tx('editor.steps.advancedSubtitle', 'Shortcuts to assemble richer experiences without losing clarity in the flow.') }}</div>
1907
1866
  </div>
1908
- </div>
1909
- <div class="cta-actions">
1910
- <button mat-stroked-button (click)="addFilesUpload()">
1867
+ <button mat-stroked-button (click)="openMoreComponents()">
1911
1868
  <mat-icon [praxisIcon]="'add'"></mat-icon>
1912
- {{ tx('editor.steps.insertUpload', 'Insert upload') }}
1869
+ {{ tx('editor.steps.moreComponents', 'More components') }}
1913
1870
  </button>
1914
1871
  </div>
1915
- </div>
1916
- </div>
1917
-
1918
- <div class="widget-list advanced-list">
1919
- <div class="widget-item" *ngFor="let w of advancedWidgets(step)">
1920
- <div class="drag-handle"><mat-icon [praxisIcon]="'extension'"></mat-icon></div>
1921
- <div class="info">
1922
- <div class="name">{{ displayWidgetName(w) }}</div>
1923
- <div class="sub">{{ w.id }}</div>
1924
- </div>
1925
- <div class="actions">
1926
- <button mat-icon-button (click)="editWidget(w)" [disabled]="!canEditWidget(w)" [matTooltip]="tx('editor.steps.editComponent', 'Edit component')">
1927
- <mat-icon [praxisIcon]="'tune'"></mat-icon>
1928
- </button>
1929
- <button mat-icon-button color="warn" (click)="removeAdvancedWidget(w)" [matTooltip]="tx('editor.steps.removeComponent', 'Remove component')">
1930
- <mat-icon [praxisIcon]="'delete'"></mat-icon>
1931
- </button>
1872
+ <div class="section-body">
1873
+ <div class="cta-grid">
1874
+ <div class="cta-row-item">
1875
+ <div class="cta-head">
1876
+ <mat-icon [praxisIcon]="'account_tree'"></mat-icon>
1877
+ <div>
1878
+ <div class="cta-title">{{ tx('editor.steps.treeListTitle', 'Tree list') }}</div>
1879
+ <div class="cta-desc">{{ tx('editor.steps.treeListDesc', 'Hierarchical data with simple selection.') }}</div>
1880
+ </div>
1881
+ </div>
1882
+ <div class="cta-actions">
1883
+ <button mat-stroked-button (click)="addTreeList()">
1884
+ <mat-icon [praxisIcon]="'add'"></mat-icon>
1885
+ {{ tx('editor.steps.insertTree', 'Insert tree') }}
1886
+ </button>
1887
+ </div>
1888
+ </div>
1889
+ <div class="cta-row-item">
1890
+ <div class="cta-head">
1891
+ <mat-icon [praxisIcon]="'swap_horiz'"></mat-icon>
1892
+ <div>
1893
+ <div class="cta-title">{{ tx('editor.steps.transferTitle', 'Item transfer') }}</div>
1894
+ <div class="cta-desc">{{ tx('editor.steps.transferDesc', 'Move items between lists for multi-selection.') }}</div>
1895
+ </div>
1896
+ </div>
1897
+ <div class="cta-actions">
1898
+ <button mat-stroked-button (click)="addTransferListQuick()">
1899
+ <mat-icon [praxisIcon]="'add'"></mat-icon>
1900
+ {{ tx('editor.steps.insertTransfer', 'Insert transfer') }}
1901
+ </button>
1902
+ </div>
1903
+ </div>
1904
+ <div class="cta-row-item">
1905
+ <div class="cta-head">
1906
+ <mat-icon [praxisIcon]="'search'"></mat-icon>
1907
+ <div>
1908
+ <div class="cta-title">{{ tx('editor.steps.searchTitle', 'Searchable selection') }}</div>
1909
+ <div class="cta-desc">{{ tx('editor.steps.searchDesc', 'Selection with local or remote search.') }}</div>
1910
+ </div>
1911
+ </div>
1912
+ <div class="cta-actions">
1913
+ <button mat-stroked-button (click)="addSearchableSelect()">
1914
+ <mat-icon [praxisIcon]="'add'"></mat-icon>
1915
+ {{ tx('editor.steps.insertSelector', 'Insert selector') }}
1916
+ </button>
1917
+ </div>
1918
+ </div>
1919
+ <div class="cta-row-item">
1920
+ <div class="cta-head">
1921
+ <mat-icon [praxisIcon]="'upload_file'"></mat-icon>
1922
+ <div>
1923
+ <div class="cta-title">{{ tx('editor.steps.uploadTitle', 'File upload') }}</div>
1924
+ <div class="cta-desc">{{ tx('editor.steps.uploadDesc', 'Attachments with validation and upload flow.') }}</div>
1925
+ </div>
1926
+ </div>
1927
+ <div class="cta-actions">
1928
+ <button mat-stroked-button (click)="addFilesUpload()">
1929
+ <mat-icon [praxisIcon]="'add'"></mat-icon>
1930
+ {{ tx('editor.steps.insertUpload', 'Insert upload') }}
1931
+ </button>
1932
+ </div>
1933
+ </div>
1934
+ </div>
1935
+ <div class="widget-list advanced-list">
1936
+ @for (w of advancedWidgets(step); track w) {
1937
+ <div class="widget-item">
1938
+ <div class="drag-handle"><mat-icon [praxisIcon]="'extension'"></mat-icon></div>
1939
+ <div class="info">
1940
+ <div class="name">{{ displayWidgetName(w) }}</div>
1941
+ <div class="sub">{{ w.id }}</div>
1942
+ </div>
1943
+ <div class="actions">
1944
+ <button mat-icon-button (click)="editWidget(w)" [disabled]="!canEditWidget(w)" [matTooltip]="tx('editor.steps.editComponent', 'Edit component')">
1945
+ <mat-icon [praxisIcon]="'tune'"></mat-icon>
1946
+ </button>
1947
+ <button mat-icon-button color="warn" (click)="removeAdvancedWidget(w)" [matTooltip]="tx('editor.steps.removeComponent', 'Remove component')">
1948
+ <mat-icon [praxisIcon]="'delete'"></mat-icon>
1949
+ </button>
1950
+ </div>
1951
+ </div>
1952
+ }
1953
+ @if (!advancedWidgets(step).length) {
1954
+ <div class="empty">{{ tx('editor.steps.emptyAdvanced', 'No advanced components added.') }}</div>
1955
+ }
1956
+ </div>
1932
1957
  </div>
1933
1958
  </div>
1934
- <div class="empty" *ngIf="!advancedWidgets(step).length">{{ tx('editor.steps.emptyAdvanced', 'No advanced components added.') }}</div>
1935
1959
  </div>
1936
1960
  </div>
1937
1961
  </div>
1938
- </div>
1939
- </div>
1940
- </div>
1941
- </div>
1942
- <ng-template #noSteps>
1943
- <div class="muted">{{ tx('editor.steps.noSteps', 'No steps defined.') }}</div>
1944
- </ng-template>
1945
- </div>
1962
+ } @else {
1963
+ <div class="muted">{{ tx('editor.steps.noSteps', 'No steps defined.') }}</div>
1964
+ }
1965
+ </div>
1966
+ </div>
1946
1967
  </mat-tab>
1947
-
1968
+
1948
1969
  <mat-tab [label]="tx('editor.navigation.tab', 'Navigation')">
1949
1970
  <div class="tab-pad">
1950
1971
  <div class="editor-intro">
@@ -2013,22 +2034,30 @@ class PraxisStepperConfigEditor {
2013
2034
  <div class="inline-action-item">
2014
2035
  <div class="section-title">{{ tx('editor.navigation.prevIcon', 'Back icon') }}</div>
2015
2036
  <button mat-stroked-button type="button" (click)="pickNavIcon('prevIcon')" [disabled]="!navigationCfg.visible" [attr.aria-label]="tx('editor.navigation.pickPrevIcon', 'Choose the Back button icon')">
2016
- <mat-icon *ngIf="navigationCfg.prevIcon" [fontIcon]="navigationCfg.prevIcon"></mat-icon>
2017
- <ng-container *ngIf="!navigationCfg.prevIcon">{{ tx('editor.shared.pick', 'Choose') }}</ng-container>
2037
+ @if (navigationCfg.prevIcon) {
2038
+ <mat-icon [fontIcon]="navigationCfg.prevIcon"></mat-icon>
2039
+ }
2040
+ @if (!navigationCfg.prevIcon) {
2041
+ {{ tx('editor.shared.pick', 'Choose') }}
2042
+ }
2018
2043
  </button>
2019
2044
  </div>
2020
2045
  <div class="inline-action-item">
2021
2046
  <div class="section-title">{{ tx('editor.navigation.nextIcon', 'Next icon') }}</div>
2022
2047
  <button mat-stroked-button type="button" (click)="pickNavIcon('nextIcon')" [disabled]="!navigationCfg.visible" [attr.aria-label]="tx('editor.navigation.pickNextIcon', 'Choose the Next button icon')">
2023
- <mat-icon *ngIf="navigationCfg.nextIcon" [fontIcon]="navigationCfg.nextIcon"></mat-icon>
2024
- <ng-container *ngIf="!navigationCfg.nextIcon">{{ tx('editor.shared.pick', 'Choose') }}</ng-container>
2048
+ @if (navigationCfg.nextIcon) {
2049
+ <mat-icon [fontIcon]="navigationCfg.nextIcon"></mat-icon>
2050
+ }
2051
+ @if (!navigationCfg.nextIcon) {
2052
+ {{ tx('editor.shared.pick', 'Choose') }}
2053
+ }
2025
2054
  </button>
2026
2055
  </div>
2027
2056
  </div>
2028
2057
  </div>
2029
2058
  </div>
2030
2059
  </mat-tab>
2031
-
2060
+
2032
2061
  <mat-tab [label]="tx('editor.appearance.tab', 'Appearance')">
2033
2062
  <div class="tab-pad">
2034
2063
  <div class="editor-intro">
@@ -2080,38 +2109,52 @@ class PraxisStepperConfigEditor {
2080
2109
  <div class="inline-action-item">
2081
2110
  <div class="section-title">{{ tx('editor.appearance.iconNumber', 'Number icon') }}</div>
2082
2111
  <button mat-stroked-button type="button" (click)="pickIcon('number')" [attr.aria-label]="tx('editor.appearance.pickIconNumber', 'Choose the number icon')">
2083
- <mat-icon *ngIf="icons.number; else pick" [fontIcon]="icons.number"></mat-icon>
2084
- <ng-template #pick>{{ tx('editor.shared.pick', 'Choose') }}</ng-template>
2112
+ @if (icons.number) {
2113
+ <mat-icon [fontIcon]="icons.number"></mat-icon>
2114
+ } @else {
2115
+ {{ tx('editor.shared.pick', 'Choose') }}
2116
+ }
2085
2117
  </button>
2086
2118
  </div>
2087
2119
  <div class="inline-action-item">
2088
2120
  <div class="section-title">{{ tx('editor.appearance.iconDone', 'Completed icon') }}</div>
2089
2121
  <button mat-stroked-button type="button" (click)="pickIcon('done')" [attr.aria-label]="tx('editor.appearance.pickIconDone', 'Choose the completed icon')">
2090
- <mat-icon *ngIf="icons.done; else pick2" [fontIcon]="icons.done"></mat-icon>
2091
- <ng-template #pick2>{{ tx('editor.shared.pick', 'Choose') }}</ng-template>
2122
+ @if (icons.done) {
2123
+ <mat-icon [fontIcon]="icons.done"></mat-icon>
2124
+ } @else {
2125
+ {{ tx('editor.shared.pick', 'Choose') }}
2126
+ }
2092
2127
  </button>
2093
2128
  </div>
2094
2129
  <div class="inline-action-item">
2095
2130
  <div class="section-title">{{ tx('editor.appearance.iconEdit', 'Edit icon') }}</div>
2096
2131
  <button mat-stroked-button type="button" (click)="pickIcon('edit')" [attr.aria-label]="tx('editor.appearance.pickIconEdit', 'Choose the edit icon')">
2097
- <mat-icon *ngIf="icons.edit; else pick3" [fontIcon]="icons.edit"></mat-icon>
2098
- <ng-template #pick3>{{ tx('editor.shared.pick', 'Choose') }}</ng-template>
2132
+ @if (icons.edit) {
2133
+ <mat-icon [fontIcon]="icons.edit"></mat-icon>
2134
+ } @else {
2135
+ {{ tx('editor.shared.pick', 'Choose') }}
2136
+ }
2099
2137
  </button>
2100
2138
  </div>
2101
2139
  <div class="inline-action-item">
2102
2140
  <div class="section-title">{{ tx('editor.appearance.iconError', 'Error icon') }}</div>
2103
2141
  <button mat-stroked-button type="button" (click)="pickIcon('error')" [attr.aria-label]="tx('editor.appearance.pickIconError', 'Choose the error icon')">
2104
- <mat-icon *ngIf="icons.error; else pick4" [fontIcon]="icons.error"></mat-icon>
2105
- <ng-template #pick4>{{ tx('editor.shared.pick', 'Choose') }}</ng-template>
2142
+ @if (icons.error) {
2143
+ <mat-icon [fontIcon]="icons.error"></mat-icon>
2144
+ } @else {
2145
+ {{ tx('editor.shared.pick', 'Choose') }}
2146
+ }
2106
2147
  </button>
2107
2148
  </div>
2108
2149
  </div>
2109
- <div class="icons-hint" *ngIf="symbolsLikelySelected.length && !appearance.iconsSet">
2110
- <div class="muted">
2111
- {{ tx('editor.appearance.symbolsHint', 'Hint: {{icons}} are Material Symbols icons. Select a Symbols set below or click').replace('{{icons}}', symbolsLikelySelected.join(', ')) }}
2112
- <button mat-button color="primary" type="button" (click)="setIconsSetToSymbols()">{{ tx('editor.appearance.useSymbols', 'Use Material Symbols (Outlined)') }}</button>.
2150
+ @if (symbolsLikelySelected.length && !appearance.iconsSet) {
2151
+ <div class="icons-hint">
2152
+ <div class="muted">
2153
+ {{ tx('editor.appearance.symbolsHint', 'Hint: {{icons}} are Material Symbols icons. Select a Symbols set below or click').replace('{{icons}}', symbolsLikelySelected.join(', ')) }}
2154
+ <button mat-button color="primary" type="button" (click)="setIconsSetToSymbols()">{{ tx('editor.appearance.useSymbols', 'Use Material Symbols (Outlined)') }}</button>.
2155
+ </div>
2113
2156
  </div>
2114
- </div>
2157
+ }
2115
2158
  <div class="pdx-appearance-actions">
2116
2159
  <button mat-stroked-button color="primary" type="button" (click)="applyPreset('neutral')">{{ tx('editor.appearance.presetNeutral', 'Preset: neutral') }}</button>
2117
2160
  <button mat-stroked-button color="primary" type="button" (click)="applyPreset('primary')">{{ tx('editor.appearance.presetPrimary', 'Preset: primary') }}</button>
@@ -2126,12 +2169,14 @@ class PraxisStepperConfigEditor {
2126
2169
  </summary>
2127
2170
  <div class="disclosure-body">
2128
2171
  <div class="tokens-grid">
2129
- <div class="token-item" *ngFor="let key of stepperTokenKeys">
2130
- <mat-form-field appearance="outline" class="w-full">
2131
- <mat-label>{{ key }}</mat-label>
2132
- <input matInput [ngModel]="appearance.tokens?.[key]" (ngModelChange)="onTokenChange(key, $event)" [placeholder]="tx('editor.appearance.tokenPlaceholder', 'CSS value or var(--token)')" />
2133
- </mat-form-field>
2134
- </div>
2172
+ @for (key of stepperTokenKeys; track key) {
2173
+ <div class="token-item">
2174
+ <mat-form-field appearance="outline" class="w-full">
2175
+ <mat-label>{{ key }}</mat-label>
2176
+ <input matInput [ngModel]="appearance.tokens?.[key]" (ngModelChange)="onTokenChange(key, $event)" [placeholder]="tx('editor.appearance.tokenPlaceholder', 'CSS value or var(--token)')" />
2177
+ </mat-form-field>
2178
+ </div>
2179
+ }
2135
2180
  </div>
2136
2181
  <div class="code-card">
2137
2182
  <div class="code-head">{{ tx('editor.appearance.scssSnippet', 'SCSS snippet') }}</div>
@@ -2143,12 +2188,11 @@ class PraxisStepperConfigEditor {
2143
2188
  </mat-tab>
2144
2189
  </mat-tab-group>
2145
2190
  </div>
2146
- `, isInline: true, styles: [".pdx-editor{display:grid;gap:16px}.pdx-editor .mat-mdc-form-field{width:100%}.pdx-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:12px}.pdx-toggles{display:flex;gap:12px;flex-wrap:wrap}.tab-pad{padding:16px;display:grid;gap:16px;background:var(--md-sys-color-surface);border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 78%,transparent);border-radius:16px}.help{color:var(--md-sys-color-on-surface-variant);font-size:13px}.editor-intro{display:flex;justify-content:space-between;gap:16px;align-items:flex-start;padding:4px 2px 2px}.editor-intro-copy{display:grid;gap:6px;max-width:760px}.eyebrow{font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--md-sys-color-on-surface-variant);font-weight:600}.editor-title{font-size:22px;line-height:1.15;font-weight:650;color:var(--md-sys-color-on-surface)}.editor-subtitle{max-width:72ch;color:var(--md-sys-color-on-surface-variant);line-height:1.45;font-size:14px}.editor-intro-meta{display:flex;gap:8px;align-items:flex-start}.meta-pill{display:grid;gap:2px;min-width:88px;padding:10px 12px;border-radius:14px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 70%,transparent);background:var(--md-sys-color-surface-container-low)}.meta-label{font-size:11px;text-transform:uppercase;letter-spacing:.06em;color:var(--md-sys-color-on-surface-variant)}.quick-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:12px;margin-bottom:6px}.icons-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:12px;margin:8px 0}.icon-item{display:grid;gap:6px;align-content:start}.icons-hint{margin-top:4px}.settings-group{display:grid;gap:14px;padding:2px 0 4px}.settings-group+.settings-group,.settings-group+.disclosure,.disclosure+.settings-group{padding-top:18px;border-top:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 60%,transparent)}.group-head{display:grid;gap:4px;max-width:72ch}.inline-actions-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:12px;align-items:start}.inline-action-item{display:grid;gap:8px;align-content:start;min-width:0}.pdx-steps{display:grid;gap:12px;padding:4px 0 2px}.steps-workspace{display:grid;grid-template-columns:minmax(260px,320px) minmax(0,1fr);gap:24px;align-items:start}.pdx-steps-header{display:flex;justify-content:space-between;align-items:center;gap:16px}.pdx-step-list{display:grid;gap:10px}.pdx-step-item{display:grid;grid-template-columns:20px 1fr auto;gap:10px;align-items:start;padding:12px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 68%,transparent);border-radius:14px;background:var(--md-sys-color-surface);cursor:pointer;outline:none}.pdx-step-item.active{border-color:color-mix(in srgb,var(--md-sys-color-primary) 55%,var(--md-sys-color-outline-variant));background:color-mix(in srgb,var(--md-sys-color-primary-container) 26%,var(--md-sys-color-surface));box-shadow:none}.pdx-step-item:focus-visible{border-color:var(--md-sys-color-primary);box-shadow:0 0 0 2px color-mix(in srgb,var(--md-sys-color-primary) 22%,transparent)}.drag-handle{display:flex;align-items:center;color:var(--md-sys-color-on-surface-variant)}.step-summary{display:grid;gap:8px;min-width:0}.step-summary-head{display:grid;gap:2px}.step-summary-index{font-size:11px;text-transform:uppercase;letter-spacing:.06em;color:var(--md-sys-color-on-surface-variant);font-weight:600}.step-summary-title{font-size:15px;line-height:1.3;font-weight:600;color:var(--md-sys-color-on-surface)}.step-summary-sub{font-size:12px;color:var(--md-sys-color-on-surface-variant);font-family:var(--md-ref-typeface-plain, monospace);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.step-summary-flags{display:flex;gap:6px;flex-wrap:wrap}.summary-chip{display:inline-flex;align-items:center;min-height:22px;padding:0 8px;border-radius:999px;background:var(--md-sys-color-surface-container-high);color:var(--md-sys-color-on-surface-variant);font-size:11px;font-weight:600}.summary-chip-warn{background:color-mix(in srgb,var(--md-sys-color-error-container) 60%,transparent);color:var(--md-sys-color-on-error-container)}.pdx-active-step{display:grid;gap:18px;min-width:0}.pdx-active-step .hdr{display:flex;gap:12px;align-items:flex-start;justify-content:space-between}.active-step-head{display:grid;gap:4px}.pdx-content-editor{display:grid;gap:16px}.section{display:grid;gap:12px;padding:0;border:none;border-radius:0;background:transparent}.section-body{display:grid;gap:12px}.section-title{font-weight:600;font-size:15px;color:var(--md-sys-color-on-surface)}.section-subtitle{font-size:13px;color:var(--md-sys-color-on-surface-variant);line-height:1.45}.section-head{display:flex;gap:12px;align-items:center;justify-content:space-between;flex-wrap:wrap}.editorial-section{padding-bottom:6px;border-bottom:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 68%,transparent)}.detail-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}.field-span-2{grid-column:span 2}.toggle-group{display:flex;gap:10px;flex-wrap:wrap;padding-top:4px}.disclosure{padding:0 0 12px;border-bottom:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 62%,transparent)}.disclosure summary{list-style:none;display:flex;justify-content:space-between;align-items:baseline;gap:16px;cursor:pointer;padding:0;position:relative}.disclosure summary::-webkit-details-marker{display:none}.disclosure summary:after{content:\"expand_more\";font-family:Material Icons;font-size:18px;color:var(--md-sys-color-on-surface-variant);transition:transform .16s ease}.disclosure[open] summary:after{transform:rotate(180deg)}.disclosure summary:focus-visible{outline:2px solid color-mix(in srgb,var(--md-sys-color-primary) 58%,transparent);outline-offset:4px;border-radius:8px}.disclosure-body{padding-top:12px}.widget-list{display:grid;gap:8px}.widget-item{display:grid;grid-template-columns:20px 1fr auto;align-items:start;gap:12px;padding:10px 0;border:none;border-radius:0;background:transparent;border-bottom:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 56%,transparent)}.widget-item .info{display:grid;gap:2px;min-width:0}.widget-item .info .name{font-weight:600}.widget-item .info .sub{font-size:12px;color:var(--md-sys-color-on-surface-variant);line-height:1.45}.widget-item .info .meta{margin-top:2px;font-size:11px;color:var(--md-sys-color-on-surface-variant);font-family:var(--md-ref-typeface-plain, monospace);opacity:.85}.widget-item .actions{display:flex;gap:2px;flex-wrap:nowrap;justify-content:flex-end;align-items:flex-start;opacity:.92}.editorial-item{align-items:start}.editorial-item .actions{justify-content:flex-end}.cta-row{display:flex;gap:8px;align-items:center}.spacer{flex:1 1 auto}.muted{color:var(--md-sys-color-on-surface-variant)}.cta-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:8px;margin-bottom:4px}.cta-row-item{display:grid;gap:10px;padding:12px 0;border-bottom:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 56%,transparent)}.tokens-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:12px;margin:8px 0}.token-item{display:contents}.pdx-appearance{margin-top:8px;display:grid;gap:8px}.pdx-appearance-actions{display:flex;gap:8px;flex-wrap:wrap}.zone-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:12px}.zone-column{display:grid;gap:10px;min-width:0}.zone-head{display:flex;align-items:center;justify-content:space-between;gap:8px}.zone-actions{display:flex;align-items:center;gap:8px;flex-wrap:wrap;justify-content:flex-end}.zone-title{font-weight:600}.zone-column+.zone-column{padding-left:16px;border-left:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 56%,transparent)}.zone-count{font-size:12px;padding:2px 8px;border-radius:999px;background:var(--md-sys-color-surface-container-high);color:var(--md-sys-color-on-surface)}.advanced-list{margin-top:4px}.form-row-card{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:10px 0;border-bottom:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 56%,transparent)}.form-row-main{display:flex;align-items:center;gap:12px;min-width:0}.form-row-actions{display:flex;gap:4px;flex-wrap:wrap;justify-content:flex-end}.code-card{margin-top:8px}.code-head{font-weight:600;margin-bottom:4px}.code{white-space:pre;overflow:auto;background:var(--md-sys-color-surface-container-highest)}.w-full{grid-column:1 / -1}.min-180{min-width:180px}.help-icon-button{--mdc-icon-button-state-layer-size: 28px;--mdc-icon-button-icon-size: 18px;width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;margin-right:-4px}.help-icon-button mat-icon{font-size:18px;width:18px;height:18px}.mat-mdc-form-field-icon-suffix{align-self:center}.cta-row-item .cta-head{display:grid;grid-template-columns:20px 1fr;align-items:start;gap:10px}.cta-row-item .cta-title{font-weight:600;color:var(--md-sys-color-on-surface)}.cta-row-item .cta-desc{font-size:12px;color:var(--md-sys-color-on-surface-variant);line-height:1.45;margin-top:2px}.cta-row-item .cta-actions{display:flex;gap:8px;align-items:center}.widget-item:last-child,.cta-row-item:last-child,.form-row-card:last-child{border-bottom:none}@media(max-width:900px){.editor-intro{flex-direction:column}.steps-workspace{grid-template-columns:1fr;gap:20px}.pdx-step-item{grid-template-columns:20px 1fr}.pdx-actions{grid-column:1 / -1;justify-self:end}.widget-item{grid-template-columns:20px 1fr}.widget-item .actions{grid-column:1 / -1;justify-content:flex-end}.form-row-card{flex-direction:column;align-items:flex-start}.form-row-actions{justify-content:flex-start}.zone-column+.zone-column{padding-left:0;border-left:none;padding-top:12px;border-top:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 56%,transparent)}}@media(max-width:640px){.tab-pad{padding:14px}.editor-title{font-size:20px}.pdx-active-step .hdr{align-items:flex-start;flex-direction:column}.detail-grid{grid-template-columns:1fr}.field-span-2{grid-column:auto}.toggle-group{flex-direction:column;align-items:flex-start}.zone-head{align-items:flex-start;flex-direction:column}.zone-actions,.widget-item .actions{justify-content:flex-start}.disclosure summary{flex-direction:column;align-items:flex-start}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i4.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4$1.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: MatButtonModule }, { kind: "component", type: i3$1.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$1.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i7.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: DragDropModule }, { kind: "directive", type: i8.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: i8.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i8.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i9.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatDialogModule }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i10.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i10.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"] }] });
2191
+ `, isInline: true, styles: [".pdx-editor{display:grid;gap:16px}.pdx-editor .mat-mdc-form-field{width:100%}.pdx-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:12px}.pdx-toggles{display:flex;gap:12px;flex-wrap:wrap}.tab-pad{padding:16px;display:grid;gap:16px;background:var(--md-sys-color-surface);border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 78%,transparent);border-radius:16px}.help{color:var(--md-sys-color-on-surface-variant);font-size:13px}.editor-intro{display:flex;justify-content:space-between;gap:16px;align-items:flex-start;padding:4px 2px 2px}.editor-intro-copy{display:grid;gap:6px;max-width:760px}.eyebrow{font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--md-sys-color-on-surface-variant);font-weight:600}.editor-title{font-size:22px;line-height:1.15;font-weight:650;color:var(--md-sys-color-on-surface)}.editor-subtitle{max-width:72ch;color:var(--md-sys-color-on-surface-variant);line-height:1.45;font-size:14px}.editor-intro-meta{display:flex;gap:8px;align-items:flex-start}.meta-pill{display:grid;gap:2px;min-width:88px;padding:10px 12px;border-radius:14px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 70%,transparent);background:var(--md-sys-color-surface-container-low)}.meta-label{font-size:11px;text-transform:uppercase;letter-spacing:.06em;color:var(--md-sys-color-on-surface-variant)}.quick-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:12px;margin-bottom:6px}.icons-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:12px;margin:8px 0}.icon-item{display:grid;gap:6px;align-content:start}.icons-hint{margin-top:4px}.settings-group{display:grid;gap:14px;padding:2px 0 4px}.settings-group+.settings-group,.settings-group+.disclosure,.disclosure+.settings-group{padding-top:18px;border-top:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 60%,transparent)}.group-head{display:grid;gap:4px;max-width:72ch}.inline-actions-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:12px;align-items:start}.inline-action-item{display:grid;gap:8px;align-content:start;min-width:0}.pdx-steps{display:grid;gap:12px;padding:4px 0 2px}.steps-workspace{display:grid;grid-template-columns:minmax(260px,320px) minmax(0,1fr);gap:24px;align-items:start}.pdx-steps-header{display:flex;justify-content:space-between;align-items:center;gap:16px}.pdx-step-list{display:grid;gap:10px}.pdx-step-item{display:grid;grid-template-columns:20px 1fr auto;gap:10px;align-items:start;padding:12px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 68%,transparent);border-radius:14px;background:var(--md-sys-color-surface);cursor:pointer;outline:none}.pdx-step-item.active{border-color:color-mix(in srgb,var(--md-sys-color-primary) 55%,var(--md-sys-color-outline-variant));background:color-mix(in srgb,var(--md-sys-color-primary-container) 26%,var(--md-sys-color-surface));box-shadow:none}.pdx-step-item:focus-visible{border-color:var(--md-sys-color-primary);box-shadow:0 0 0 2px color-mix(in srgb,var(--md-sys-color-primary) 22%,transparent)}.drag-handle{display:flex;align-items:center;color:var(--md-sys-color-on-surface-variant)}.step-summary{display:grid;gap:8px;min-width:0}.step-summary-head{display:grid;gap:2px}.step-summary-index{font-size:11px;text-transform:uppercase;letter-spacing:.06em;color:var(--md-sys-color-on-surface-variant);font-weight:600}.step-summary-title{font-size:15px;line-height:1.3;font-weight:600;color:var(--md-sys-color-on-surface)}.step-summary-sub{font-size:12px;color:var(--md-sys-color-on-surface-variant);font-family:var(--md-ref-typeface-plain, monospace);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.step-summary-flags{display:flex;gap:6px;flex-wrap:wrap}.summary-chip{display:inline-flex;align-items:center;min-height:22px;padding:0 8px;border-radius:999px;background:var(--md-sys-color-surface-container-high);color:var(--md-sys-color-on-surface-variant);font-size:11px;font-weight:600}.summary-chip-warn{background:color-mix(in srgb,var(--md-sys-color-error-container) 60%,transparent);color:var(--md-sys-color-on-error-container)}.pdx-active-step{display:grid;gap:18px;min-width:0}.pdx-active-step .hdr{display:flex;gap:12px;align-items:flex-start;justify-content:space-between}.active-step-head{display:grid;gap:4px}.pdx-content-editor{display:grid;gap:16px}.section{display:grid;gap:12px;padding:0;border:none;border-radius:0;background:transparent}.section-body{display:grid;gap:12px}.section-title{font-weight:600;font-size:15px;color:var(--md-sys-color-on-surface)}.section-subtitle{font-size:13px;color:var(--md-sys-color-on-surface-variant);line-height:1.45}.section-head{display:flex;gap:12px;align-items:center;justify-content:space-between;flex-wrap:wrap}.editorial-section{padding-bottom:6px;border-bottom:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 68%,transparent)}.detail-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}.field-span-2{grid-column:span 2}.toggle-group{display:flex;gap:10px;flex-wrap:wrap;padding-top:4px}.disclosure{padding:0 0 12px;border-bottom:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 62%,transparent)}.disclosure summary{list-style:none;display:flex;justify-content:space-between;align-items:baseline;gap:16px;cursor:pointer;padding:0;position:relative}.disclosure summary::-webkit-details-marker{display:none}.disclosure summary:after{content:\"expand_more\";font-family:Material Icons;font-size:18px;color:var(--md-sys-color-on-surface-variant);transition:transform .16s ease}.disclosure[open] summary:after{transform:rotate(180deg)}.disclosure summary:focus-visible{outline:2px solid color-mix(in srgb,var(--md-sys-color-primary) 58%,transparent);outline-offset:4px;border-radius:8px}.disclosure-body{padding-top:12px}.widget-list{display:grid;gap:8px}.widget-item{display:grid;grid-template-columns:20px 1fr auto;align-items:start;gap:12px;padding:10px 0;border:none;border-radius:0;background:transparent;border-bottom:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 56%,transparent)}.widget-item .info{display:grid;gap:2px;min-width:0}.widget-item .info .name{font-weight:600}.widget-item .info .sub{font-size:12px;color:var(--md-sys-color-on-surface-variant);line-height:1.45}.widget-item .info .meta{margin-top:2px;font-size:11px;color:var(--md-sys-color-on-surface-variant);font-family:var(--md-ref-typeface-plain, monospace);opacity:.85}.widget-item .actions{display:flex;gap:2px;flex-wrap:nowrap;justify-content:flex-end;align-items:flex-start;opacity:.92}.editorial-item{align-items:start}.editorial-item .actions{justify-content:flex-end}.cta-row{display:flex;gap:8px;align-items:center}.spacer{flex:1 1 auto}.muted{color:var(--md-sys-color-on-surface-variant)}.cta-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:8px;margin-bottom:4px}.cta-row-item{display:grid;gap:10px;padding:12px 0;border-bottom:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 56%,transparent)}.tokens-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:12px;margin:8px 0}.token-item{display:contents}.pdx-appearance{margin-top:8px;display:grid;gap:8px}.pdx-appearance-actions{display:flex;gap:8px;flex-wrap:wrap}.zone-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:12px}.zone-column{display:grid;gap:10px;min-width:0}.zone-head{display:flex;align-items:center;justify-content:space-between;gap:8px}.zone-actions{display:flex;align-items:center;gap:8px;flex-wrap:wrap;justify-content:flex-end}.zone-title{font-weight:600}.zone-column+.zone-column{padding-left:16px;border-left:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 56%,transparent)}.zone-count{font-size:12px;padding:2px 8px;border-radius:999px;background:var(--md-sys-color-surface-container-high);color:var(--md-sys-color-on-surface)}.advanced-list{margin-top:4px}.form-row-card{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:10px 0;border-bottom:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 56%,transparent)}.form-row-main{display:flex;align-items:center;gap:12px;min-width:0}.form-row-actions{display:flex;gap:4px;flex-wrap:wrap;justify-content:flex-end}.code-card{margin-top:8px}.code-head{font-weight:600;margin-bottom:4px}.code{white-space:pre;overflow:auto;background:var(--md-sys-color-surface-container-highest)}.w-full{grid-column:1 / -1}.min-180{min-width:180px}.help-icon-button{--mdc-icon-button-state-layer-size: 28px;--mdc-icon-button-icon-size: 18px;width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;margin-right:-4px}.help-icon-button mat-icon{font-size:18px;width:18px;height:18px}.mat-mdc-form-field-icon-suffix{align-self:center}.cta-row-item .cta-head{display:grid;grid-template-columns:20px 1fr;align-items:start;gap:10px}.cta-row-item .cta-title{font-weight:600;color:var(--md-sys-color-on-surface)}.cta-row-item .cta-desc{font-size:12px;color:var(--md-sys-color-on-surface-variant);line-height:1.45;margin-top:2px}.cta-row-item .cta-actions{display:flex;gap:8px;align-items:center}.widget-item:last-child,.cta-row-item:last-child,.form-row-card:last-child{border-bottom:none}@media(max-width:900px){.editor-intro{flex-direction:column}.steps-workspace{grid-template-columns:1fr;gap:20px}.pdx-step-item{grid-template-columns:20px 1fr}.pdx-actions{grid-column:1 / -1;justify-self:end}.widget-item{grid-template-columns:20px 1fr}.widget-item .actions{grid-column:1 / -1;justify-content:flex-end}.form-row-card{flex-direction:column;align-items:flex-start}.form-row-actions{justify-content:flex-start}.zone-column+.zone-column{padding-left:0;border-left:none;padding-top:12px;border-top:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 56%,transparent)}}@media(max-width:640px){.tab-pad{padding:14px}.editor-title{font-size:20px}.pdx-active-step .hdr{align-items:flex-start;flex-direction:column}.detail-grid{grid-template-columns:1fr}.field-span-2{grid-column:auto}.toggle-group{flex-direction:column;align-items:flex-start}.zone-head{align-items:flex-start;flex-direction:column}.zone-actions,.widget-item .actions{justify-content:flex-start}.disclosure summary{flex-direction:column;align-items:flex-start}}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.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$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i4.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4$1.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: MatButtonModule }, { kind: "component", type: i3$1.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$1.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i6.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: DragDropModule }, { kind: "directive", type: i7.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: i7.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i7.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatDialogModule }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i9.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i9.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"] }] });
2147
2192
  }
2148
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisStepperConfigEditor, decorators: [{
2193
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisStepperConfigEditor, decorators: [{
2149
2194
  type: Component,
2150
2195
  args: [{ selector: 'praxis-stepper-config-editor', standalone: true, imports: [
2151
- CommonModule,
2152
2196
  FormsModule,
2153
2197
  MatFormFieldModule,
2154
2198
  MatInputModule,
@@ -2159,7 +2203,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
2159
2203
  DragDropModule,
2160
2204
  MatTooltipModule,
2161
2205
  MatDialogModule,
2162
- MatTabsModule,
2206
+ MatTabsModule
2163
2207
  ], providers: [providePraxisStepperI18n()], template: `
2164
2208
  <div class="pdx-editor">
2165
2209
  <mat-tab-group>
@@ -2243,7 +2287,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
2243
2287
  </details>
2244
2288
  </div>
2245
2289
  </mat-tab>
2246
-
2290
+
2247
2291
  <mat-tab [label]="tx('editor.tabs.steps', 'Steps')">
2248
2292
  <div class="tab-pad">
2249
2293
  <div class="editor-intro">
@@ -2267,295 +2311,299 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
2267
2311
  </div>
2268
2312
  <button mat-flat-button color="primary" (click)="addStep()"><mat-icon [praxisIcon]="'add'"></mat-icon>{{ tx('editor.steps.add', 'Add step') }}</button>
2269
2313
  </div>
2270
- <div class="steps-workspace" *ngIf="activeStep as step; else noSteps">
2271
- <div
2272
- cdkDropList
2273
- role="listbox"
2274
- [attr.aria-label]="tx('editor.steps.listAria', 'Step list')"
2275
- (cdkDropListDropped)="drop($event)"
2276
- class="pdx-step-list">
2314
+ @if (activeStep; as step) {
2315
+ <div class="steps-workspace">
2277
2316
  <div
2278
- class="pdx-step-item"
2279
- *ngFor="let s of config.steps; let i = index"
2280
- cdkDrag
2281
- role="option"
2282
- [attr.aria-selected]="activeStep === s"
2283
- [attr.tabindex]="activeStep === s ? 0 : -1"
2284
- [class.active]="activeStep === s"
2285
- (click)="setActive(s)"
2286
- (keydown.enter)="onStepItemEnter($event, s)"
2287
- (keydown.space)="onStepItemSpace($event, s)"
2288
- (keydown.arrowdown)="focusAdjacentStep($event, i, 1)"
2289
- (keydown.arrowup)="focusAdjacentStep($event, i, -1)">
2290
- <div class="drag-handle" cdkDragHandle><mat-icon [praxisIcon]="'drag_indicator'"></mat-icon></div>
2291
- <div class="step-summary">
2292
- <div class="step-summary-head">
2293
- <div class="step-summary-index">{{ stepIndexLabel(i) }}</div>
2294
- <div class="step-summary-title">{{ s.label || tx('editor.steps.untitled', 'Untitled') }}</div>
2295
- </div>
2296
- <div class="step-summary-sub">{{ s.id || tx('editor.steps.noId', 'No identifier') }}</div>
2297
- <div class="step-summary-flags">
2298
- <span class="summary-chip" *ngIf="s.optional">{{ tx('editor.steps.optional', 'Optional') }}</span>
2299
- <span class="summary-chip" *ngIf="s.completed">{{ tx('editor.steps.completed', 'Completed') }}</span>
2300
- <span class="summary-chip summary-chip-warn" *ngIf="s.hasError">{{ tx('editor.steps.error', 'Error') }}</span>
2301
- <span class="summary-chip" *ngIf="s.form">{{ tx('editor.steps.form', 'Form') }}</span>
2302
- </div>
2303
- </div>
2304
- <div class="pdx-actions">
2305
- <button mat-icon-button color="warn" (click)="removeStep(i); $event.stopPropagation()" [matTooltip]="tx('editor.steps.remove', 'Remove')" [attr.aria-label]="stepRemoveAria(s, i)">
2306
- <mat-icon [praxisIcon]="'delete'"></mat-icon>
2307
- </button>
2308
- </div>
2309
- </div>
2310
- </div>
2311
-
2312
- <div class="pdx-active-step">
2313
- <div class="hdr">
2314
- <div class="active-step-head">
2315
- <div class="eyebrow">{{ tx('editor.steps.selectedEyebrow', 'Selected step') }}</div>
2316
- <div class="title">{{ editingStepTitle(step) }}</div>
2317
- <div class="section-subtitle">{{ tx('editor.steps.selectedSubtitle', 'Adjust the main content first. Secondary settings stay collapsed to reduce noise.') }}</div>
2318
- </div>
2319
- </div>
2320
-
2321
- <div class="section">
2322
- <div class="section-title">{{ tx('editor.steps.mainData', 'Main data') }}</div>
2323
- <div class="detail-grid">
2324
- <mat-form-field appearance="outline" class="field-span-2">
2325
- <mat-label>{{ tx('editor.steps.stepTitle', 'Step title') }}</mat-label>
2326
- <input matInput [(ngModel)]="step.label" (ngModelChange)="markDirty()" />
2327
- </mat-form-field>
2328
- <mat-form-field appearance="outline">
2329
- <mat-label>{{ tx('editor.steps.identifier', 'Identifier') }}</mat-label>
2330
- <input matInput [(ngModel)]="step.id" (ngModelChange)="markDirty()" />
2331
- </mat-form-field>
2332
- <mat-form-field appearance="outline">
2333
- <mat-label>{{ tx('editor.steps.iconOrState', 'Icon or state') }}</mat-label>
2334
- <input matInput [(ngModel)]="step.state" (ngModelChange)="markDirty()" [placeholder]="tx('editor.steps.iconOrStatePlaceholder', 'e.g.: number, done, edit')" />
2335
- </mat-form-field>
2336
- <mat-form-field appearance="outline" class="field-span-2">
2337
- <mat-label>{{ tx('editor.steps.errorMessage', 'Error message') }}</mat-label>
2338
- <input matInput [(ngModel)]="step.errorMessage" (ngModelChange)="markDirty()" />
2339
- </mat-form-field>
2340
- </div>
2341
- <div class="toggle-group">
2342
- <mat-slide-toggle [(ngModel)]="step.optional" (ngModelChange)="markDirty()">{{ tx('editor.steps.optionalToggle', 'Optional step') }}</mat-slide-toggle>
2343
- <mat-slide-toggle [(ngModel)]="step.editable" (ngModelChange)="markDirty()">{{ tx('editor.steps.editableToggle', 'Allow going back and editing') }}</mat-slide-toggle>
2344
- <mat-slide-toggle [(ngModel)]="step.completed" (ngModelChange)="markDirty()">{{ tx('editor.steps.completedToggle', 'Mark as completed') }}</mat-slide-toggle>
2345
- <mat-slide-toggle [(ngModel)]="step.hasError" (ngModelChange)="markDirty()">{{ tx('editor.steps.errorToggle', 'Mark as error') }}</mat-slide-toggle>
2346
- </div>
2347
- </div>
2348
-
2349
- <details class="disclosure">
2350
- <summary>
2351
- <span class="section-title">{{ tx('editor.steps.accessibilityTitle', 'Accessibility and technical details') }}</span>
2352
- <span class="section-subtitle">{{ tx('editor.steps.accessibilitySubtitle', 'Auxiliary labels and less-used metadata.') }}</span>
2353
- </summary>
2354
- <div class="detail-grid disclosure-body">
2355
- <mat-form-field appearance="outline">
2356
- <mat-label>{{ tx('editor.steps.altText', 'Alternative text') }}</mat-label>
2357
- <input matInput [(ngModel)]="step.ariaLabel" (ngModelChange)="markDirty()" />
2358
- </mat-form-field>
2359
- <mat-form-field appearance="outline">
2360
- <mat-label>{{ tx('editor.steps.describedBy', 'Described-by ID') }}</mat-label>
2361
- <input matInput [(ngModel)]="step.ariaLabelledby" (ngModelChange)="markDirty()" />
2362
- </mat-form-field>
2363
- </div>
2364
- </details>
2365
-
2366
- <div class="pdx-content-editor">
2367
- <div class="section editorial-section">
2368
- <div class="section-head">
2369
- <div>
2370
- <div class="section-title">{{ tx('editor.steps.editorialTitle', 'Editorial content') }}</div>
2371
- <div class="section-subtitle">{{ tx('editor.steps.editorialSubtitle', 'Use supporting blocks to contextualize the step before or after the form.') }}</div>
2372
- </div>
2373
- </div>
2374
-
2375
- <div class="zone-grid">
2376
- <div class="zone-column">
2377
- <div class="zone-head">
2378
- <div class="zone-title">{{ tx('editor.steps.zoneBefore', 'Before form') }}</div>
2379
- <div class="zone-actions">
2380
- <span class="zone-count">{{ richContentNodeCount(step.stepBlocksBeforeForm) }}</span>
2381
- <button mat-stroked-button type="button" (click)="seedRichContent(step, 'before')">
2382
- <mat-icon [praxisIcon]="'auto_awesome'"></mat-icon>
2383
- {{ tx('editor.steps.seedRichContent', 'Seed') }}
2384
- </button>
2317
+ cdkDropList
2318
+ role="listbox"
2319
+ [attr.aria-label]="tx('editor.steps.listAria', 'Step list')"
2320
+ (cdkDropListDropped)="drop($event)"
2321
+ class="pdx-step-list">
2322
+ @for (s of config.steps; track s; let i = $index) {
2323
+ <div
2324
+ class="pdx-step-item"
2325
+ cdkDrag
2326
+ role="option"
2327
+ [attr.aria-selected]="activeStep === s"
2328
+ [attr.tabindex]="activeStep === s ? 0 : -1"
2329
+ [class.active]="activeStep === s"
2330
+ (click)="setActive(s)"
2331
+ (keydown.enter)="onStepItemEnter($event, s)"
2332
+ (keydown.space)="onStepItemSpace($event, s)"
2333
+ (keydown.arrowdown)="focusAdjacentStep($event, i, 1)"
2334
+ (keydown.arrowup)="focusAdjacentStep($event, i, -1)">
2335
+ <div class="drag-handle" cdkDragHandle><mat-icon [praxisIcon]="'drag_indicator'"></mat-icon></div>
2336
+ <div class="step-summary">
2337
+ <div class="step-summary-head">
2338
+ <div class="step-summary-index">{{ stepIndexLabel(i) }}</div>
2339
+ <div class="step-summary-title">{{ s.label || tx('editor.steps.untitled', 'Untitled') }}</div>
2340
+ </div>
2341
+ <div class="step-summary-sub">{{ s.id || tx('editor.steps.noId', 'No identifier') }}</div>
2342
+ <div class="step-summary-flags">
2343
+ @if (s.optional) {
2344
+ <span class="summary-chip">{{ tx('editor.steps.optional', 'Optional') }}</span>
2345
+ }
2346
+ @if (s.completed) {
2347
+ <span class="summary-chip">{{ tx('editor.steps.completed', 'Completed') }}</span>
2348
+ }
2349
+ @if (s.hasError) {
2350
+ <span class="summary-chip summary-chip-warn">{{ tx('editor.steps.error', 'Error') }}</span>
2351
+ }
2352
+ @if (s.form) {
2353
+ <span class="summary-chip">{{ tx('editor.steps.form', 'Form') }}</span>
2354
+ }
2355
+ </div>
2385
2356
  </div>
2386
- </div>
2387
- <mat-form-field appearance="outline" class="w-full rich-content-json">
2388
- <mat-label>{{ tx('editor.steps.richContentDocument', 'RichContentDocument JSON') }}</mat-label>
2389
- <textarea
2390
- matInput
2391
- rows="12"
2392
- [ngModel]="richContentJson(step, 'before')"
2393
- (ngModelChange)="setRichContentJson(step, 'before', $event)"
2394
- ></textarea>
2395
- </mat-form-field>
2396
- <button mat-button color="warn" type="button" (click)="clearRichContent(step, 'before')">
2397
- <mat-icon [praxisIcon]="'delete'"></mat-icon>
2398
- {{ tx('editor.steps.clearZone', 'Clear zone') }}
2399
- </button>
2400
- </div>
2401
-
2402
- <div class="zone-column">
2403
- <div class="zone-head">
2404
- <div class="zone-title">{{ tx('editor.steps.zoneAfter', 'After form') }}</div>
2405
- <div class="zone-actions">
2406
- <span class="zone-count">{{ richContentNodeCount(step.stepBlocksAfterForm) }}</span>
2407
- <button mat-stroked-button type="button" (click)="seedRichContent(step, 'after')">
2408
- <mat-icon [praxisIcon]="'auto_awesome'"></mat-icon>
2409
- {{ tx('editor.steps.seedRichContent', 'Seed') }}
2357
+ <div class="pdx-actions">
2358
+ <button mat-icon-button color="warn" (click)="removeStep(i); $event.stopPropagation()" [matTooltip]="tx('editor.steps.remove', 'Remove')" [attr.aria-label]="stepRemoveAria(s, i)">
2359
+ <mat-icon [praxisIcon]="'delete'"></mat-icon>
2410
2360
  </button>
2411
2361
  </div>
2412
2362
  </div>
2413
- <mat-form-field appearance="outline" class="w-full rich-content-json">
2414
- <mat-label>{{ tx('editor.steps.richContentDocument', 'RichContentDocument JSON') }}</mat-label>
2415
- <textarea
2416
- matInput
2417
- rows="12"
2418
- [ngModel]="richContentJson(step, 'after')"
2419
- (ngModelChange)="setRichContentJson(step, 'after', $event)"
2420
- ></textarea>
2421
- </mat-form-field>
2422
- <button mat-button color="warn" type="button" (click)="clearRichContent(step, 'after')">
2423
- <mat-icon [praxisIcon]="'delete'"></mat-icon>
2424
- {{ tx('editor.steps.clearZone', 'Clear zone') }}
2425
- </button>
2426
- </div>
2363
+ }
2427
2364
  </div>
2428
- </div>
2429
-
2430
- <div class="section">
2431
- <div class="section-title">{{ tx('editor.steps.formSectionTitle', 'Step form') }}</div>
2432
- <div class="section-body">
2433
- <ng-container *ngIf="step.form; else addFormBtn">
2434
- <div class="form-row-card">
2435
- <div class="form-row-main">
2436
- <mat-icon [praxisIcon]="'dynamic_form'"></mat-icon>
2437
- <div>
2438
- <div class="name">{{ tx('editor.steps.mainFormTitle', 'Main form') }}</div>
2439
- <div class="sub">{{ step.form.formId || step.id || '—' }}</div>
2440
- </div>
2441
- </div>
2442
- <div class="form-row-actions">
2443
- <button mat-button (click)="editMainForm()"><mat-icon [praxisIcon]="'tune'"></mat-icon>{{ tx('editor.steps.edit', 'Edit') }}</button>
2444
- <button mat-button color="warn" (click)="removeMainForm()"><mat-icon [praxisIcon]="'delete'"></mat-icon>{{ tx('editor.steps.remove', 'Remove') }}</button>
2445
- </div>
2365
+ <div class="pdx-active-step">
2366
+ <div class="hdr">
2367
+ <div class="active-step-head">
2368
+ <div class="eyebrow">{{ tx('editor.steps.selectedEyebrow', 'Selected step') }}</div>
2369
+ <div class="title">{{ editingStepTitle(step) }}</div>
2370
+ <div class="section-subtitle">{{ tx('editor.steps.selectedSubtitle', 'Adjust the main content first. Secondary settings stay collapsed to reduce noise.') }}</div>
2446
2371
  </div>
2447
- </ng-container>
2448
- <ng-template #addFormBtn>
2449
- <button mat-stroked-button color="primary" (click)="addMainForm()"><mat-icon [praxisIcon]="'add'"></mat-icon>{{ tx('editor.steps.addForm', 'Add form') }}</button>
2450
- </ng-template>
2451
- </div>
2452
- </div>
2453
-
2454
- <div class="section">
2455
- <div class="section-head">
2456
- <div>
2457
- <div class="section-title">{{ tx('editor.steps.advancedTitle', 'Advanced components') }}</div>
2458
- <div class="section-subtitle">{{ tx('editor.steps.advancedSubtitle', 'Shortcuts to assemble richer experiences without losing clarity in the flow.') }}</div>
2459
2372
  </div>
2460
- <button mat-stroked-button (click)="openMoreComponents()">
2461
- <mat-icon [praxisIcon]="'add'"></mat-icon>
2462
- {{ tx('editor.steps.moreComponents', 'More components') }}
2463
- </button>
2464
- </div>
2465
- <div class="section-body">
2466
- <div class="cta-grid">
2467
- <div class="cta-row-item">
2468
- <div class="cta-head">
2469
- <mat-icon [praxisIcon]="'account_tree'"></mat-icon>
2470
- <div>
2471
- <div class="cta-title">{{ tx('editor.steps.treeListTitle', 'Tree list') }}</div>
2472
- <div class="cta-desc">{{ tx('editor.steps.treeListDesc', 'Hierarchical data with simple selection.') }}</div>
2473
- </div>
2474
- </div>
2475
- <div class="cta-actions">
2476
- <button mat-stroked-button (click)="addTreeList()">
2477
- <mat-icon [praxisIcon]="'add'"></mat-icon>
2478
- {{ tx('editor.steps.insertTree', 'Insert tree') }}
2479
- </button>
2480
- </div>
2373
+ <div class="section">
2374
+ <div class="section-title">{{ tx('editor.steps.mainData', 'Main data') }}</div>
2375
+ <div class="detail-grid">
2376
+ <mat-form-field appearance="outline" class="field-span-2">
2377
+ <mat-label>{{ tx('editor.steps.stepTitle', 'Step title') }}</mat-label>
2378
+ <input matInput [(ngModel)]="step.label" (ngModelChange)="markDirty()" />
2379
+ </mat-form-field>
2380
+ <mat-form-field appearance="outline">
2381
+ <mat-label>{{ tx('editor.steps.identifier', 'Identifier') }}</mat-label>
2382
+ <input matInput [(ngModel)]="step.id" (ngModelChange)="markDirty()" />
2383
+ </mat-form-field>
2384
+ <mat-form-field appearance="outline">
2385
+ <mat-label>{{ tx('editor.steps.iconOrState', 'Icon or state') }}</mat-label>
2386
+ <input matInput [(ngModel)]="step.state" (ngModelChange)="markDirty()" [placeholder]="tx('editor.steps.iconOrStatePlaceholder', 'e.g.: number, done, edit')" />
2387
+ </mat-form-field>
2388
+ <mat-form-field appearance="outline" class="field-span-2">
2389
+ <mat-label>{{ tx('editor.steps.errorMessage', 'Error message') }}</mat-label>
2390
+ <input matInput [(ngModel)]="step.errorMessage" (ngModelChange)="markDirty()" />
2391
+ </mat-form-field>
2481
2392
  </div>
2482
- <div class="cta-row-item">
2483
- <div class="cta-head">
2484
- <mat-icon [praxisIcon]="'swap_horiz'"></mat-icon>
2393
+ <div class="toggle-group">
2394
+ <mat-slide-toggle [(ngModel)]="step.optional" (ngModelChange)="markDirty()">{{ tx('editor.steps.optionalToggle', 'Optional step') }}</mat-slide-toggle>
2395
+ <mat-slide-toggle [(ngModel)]="step.editable" (ngModelChange)="markDirty()">{{ tx('editor.steps.editableToggle', 'Allow going back and editing') }}</mat-slide-toggle>
2396
+ <mat-slide-toggle [(ngModel)]="step.completed" (ngModelChange)="markDirty()">{{ tx('editor.steps.completedToggle', 'Mark as completed') }}</mat-slide-toggle>
2397
+ <mat-slide-toggle [(ngModel)]="step.hasError" (ngModelChange)="markDirty()">{{ tx('editor.steps.errorToggle', 'Mark as error') }}</mat-slide-toggle>
2398
+ </div>
2399
+ </div>
2400
+ <details class="disclosure">
2401
+ <summary>
2402
+ <span class="section-title">{{ tx('editor.steps.accessibilityTitle', 'Accessibility and technical details') }}</span>
2403
+ <span class="section-subtitle">{{ tx('editor.steps.accessibilitySubtitle', 'Auxiliary labels and less-used metadata.') }}</span>
2404
+ </summary>
2405
+ <div class="detail-grid disclosure-body">
2406
+ <mat-form-field appearance="outline">
2407
+ <mat-label>{{ tx('editor.steps.altText', 'Alternative text') }}</mat-label>
2408
+ <input matInput [(ngModel)]="step.ariaLabel" (ngModelChange)="markDirty()" />
2409
+ </mat-form-field>
2410
+ <mat-form-field appearance="outline">
2411
+ <mat-label>{{ tx('editor.steps.describedBy', 'Described-by ID') }}</mat-label>
2412
+ <input matInput [(ngModel)]="step.ariaLabelledby" (ngModelChange)="markDirty()" />
2413
+ </mat-form-field>
2414
+ </div>
2415
+ </details>
2416
+ <div class="pdx-content-editor">
2417
+ <div class="section editorial-section">
2418
+ <div class="section-head">
2485
2419
  <div>
2486
- <div class="cta-title">{{ tx('editor.steps.transferTitle', 'Item transfer') }}</div>
2487
- <div class="cta-desc">{{ tx('editor.steps.transferDesc', 'Move items between lists for multi-selection.') }}</div>
2420
+ <div class="section-title">{{ tx('editor.steps.editorialTitle', 'Editorial content') }}</div>
2421
+ <div class="section-subtitle">{{ tx('editor.steps.editorialSubtitle', 'Use supporting blocks to contextualize the step before or after the form.') }}</div>
2488
2422
  </div>
2489
2423
  </div>
2490
- <div class="cta-actions">
2491
- <button mat-stroked-button (click)="addTransferListQuick()">
2492
- <mat-icon [praxisIcon]="'add'"></mat-icon>
2493
- {{ tx('editor.steps.insertTransfer', 'Insert transfer') }}
2494
- </button>
2495
- </div>
2496
- </div>
2497
- <div class="cta-row-item">
2498
- <div class="cta-head">
2499
- <mat-icon [praxisIcon]="'search'"></mat-icon>
2500
- <div>
2501
- <div class="cta-title">{{ tx('editor.steps.searchTitle', 'Searchable selection') }}</div>
2502
- <div class="cta-desc">{{ tx('editor.steps.searchDesc', 'Selection with local or remote search.') }}</div>
2424
+ <div class="zone-grid">
2425
+ <div class="zone-column">
2426
+ <div class="zone-head">
2427
+ <div class="zone-title">{{ tx('editor.steps.zoneBefore', 'Before form') }}</div>
2428
+ <div class="zone-actions">
2429
+ <span class="zone-count">{{ richContentNodeCount(step.stepBlocksBeforeForm) }}</span>
2430
+ <button mat-stroked-button type="button" (click)="seedRichContent(step, 'before')">
2431
+ <mat-icon [praxisIcon]="'auto_awesome'"></mat-icon>
2432
+ {{ tx('editor.steps.seedRichContent', 'Seed') }}
2433
+ </button>
2434
+ </div>
2435
+ </div>
2436
+ <mat-form-field appearance="outline" class="w-full rich-content-json">
2437
+ <mat-label>{{ tx('editor.steps.richContentDocument', 'RichContentDocument JSON') }}</mat-label>
2438
+ <textarea
2439
+ matInput
2440
+ rows="12"
2441
+ [ngModel]="richContentJson(step, 'before')"
2442
+ (ngModelChange)="setRichContentJson(step, 'before', $event)"
2443
+ ></textarea>
2444
+ </mat-form-field>
2445
+ <button mat-button color="warn" type="button" (click)="clearRichContent(step, 'before')">
2446
+ <mat-icon [praxisIcon]="'delete'"></mat-icon>
2447
+ {{ tx('editor.steps.clearZone', 'Clear zone') }}
2448
+ </button>
2449
+ </div>
2450
+ <div class="zone-column">
2451
+ <div class="zone-head">
2452
+ <div class="zone-title">{{ tx('editor.steps.zoneAfter', 'After form') }}</div>
2453
+ <div class="zone-actions">
2454
+ <span class="zone-count">{{ richContentNodeCount(step.stepBlocksAfterForm) }}</span>
2455
+ <button mat-stroked-button type="button" (click)="seedRichContent(step, 'after')">
2456
+ <mat-icon [praxisIcon]="'auto_awesome'"></mat-icon>
2457
+ {{ tx('editor.steps.seedRichContent', 'Seed') }}
2458
+ </button>
2459
+ </div>
2460
+ </div>
2461
+ <mat-form-field appearance="outline" class="w-full rich-content-json">
2462
+ <mat-label>{{ tx('editor.steps.richContentDocument', 'RichContentDocument JSON') }}</mat-label>
2463
+ <textarea
2464
+ matInput
2465
+ rows="12"
2466
+ [ngModel]="richContentJson(step, 'after')"
2467
+ (ngModelChange)="setRichContentJson(step, 'after', $event)"
2468
+ ></textarea>
2469
+ </mat-form-field>
2470
+ <button mat-button color="warn" type="button" (click)="clearRichContent(step, 'after')">
2471
+ <mat-icon [praxisIcon]="'delete'"></mat-icon>
2472
+ {{ tx('editor.steps.clearZone', 'Clear zone') }}
2473
+ </button>
2503
2474
  </div>
2504
2475
  </div>
2505
- <div class="cta-actions">
2506
- <button mat-stroked-button (click)="addSearchableSelect()">
2507
- <mat-icon [praxisIcon]="'add'"></mat-icon>
2508
- {{ tx('editor.steps.insertSelector', 'Insert selector') }}
2509
- </button>
2476
+ </div>
2477
+ <div class="section">
2478
+ <div class="section-title">{{ tx('editor.steps.formSectionTitle', 'Step form') }}</div>
2479
+ <div class="section-body">
2480
+ @if (step.form) {
2481
+ <div class="form-row-card">
2482
+ <div class="form-row-main">
2483
+ <mat-icon [praxisIcon]="'dynamic_form'"></mat-icon>
2484
+ <div>
2485
+ <div class="name">{{ tx('editor.steps.mainFormTitle', 'Main form') }}</div>
2486
+ <div class="sub">{{ step.form.formId || step.id || '—' }}</div>
2487
+ </div>
2488
+ </div>
2489
+ <div class="form-row-actions">
2490
+ <button mat-button (click)="editMainForm()"><mat-icon [praxisIcon]="'tune'"></mat-icon>{{ tx('editor.steps.edit', 'Edit') }}</button>
2491
+ <button mat-button color="warn" (click)="removeMainForm()"><mat-icon [praxisIcon]="'delete'"></mat-icon>{{ tx('editor.steps.remove', 'Remove') }}</button>
2492
+ </div>
2493
+ </div>
2494
+ } @else {
2495
+ <button mat-stroked-button color="primary" (click)="addMainForm()"><mat-icon [praxisIcon]="'add'"></mat-icon>{{ tx('editor.steps.addForm', 'Add form') }}</button>
2496
+ }
2510
2497
  </div>
2511
2498
  </div>
2512
- <div class="cta-row-item">
2513
- <div class="cta-head">
2514
- <mat-icon [praxisIcon]="'upload_file'"></mat-icon>
2499
+ <div class="section">
2500
+ <div class="section-head">
2515
2501
  <div>
2516
- <div class="cta-title">{{ tx('editor.steps.uploadTitle', 'File upload') }}</div>
2517
- <div class="cta-desc">{{ tx('editor.steps.uploadDesc', 'Attachments with validation and upload flow.') }}</div>
2502
+ <div class="section-title">{{ tx('editor.steps.advancedTitle', 'Advanced components') }}</div>
2503
+ <div class="section-subtitle">{{ tx('editor.steps.advancedSubtitle', 'Shortcuts to assemble richer experiences without losing clarity in the flow.') }}</div>
2518
2504
  </div>
2519
- </div>
2520
- <div class="cta-actions">
2521
- <button mat-stroked-button (click)="addFilesUpload()">
2505
+ <button mat-stroked-button (click)="openMoreComponents()">
2522
2506
  <mat-icon [praxisIcon]="'add'"></mat-icon>
2523
- {{ tx('editor.steps.insertUpload', 'Insert upload') }}
2507
+ {{ tx('editor.steps.moreComponents', 'More components') }}
2524
2508
  </button>
2525
2509
  </div>
2526
- </div>
2527
- </div>
2528
-
2529
- <div class="widget-list advanced-list">
2530
- <div class="widget-item" *ngFor="let w of advancedWidgets(step)">
2531
- <div class="drag-handle"><mat-icon [praxisIcon]="'extension'"></mat-icon></div>
2532
- <div class="info">
2533
- <div class="name">{{ displayWidgetName(w) }}</div>
2534
- <div class="sub">{{ w.id }}</div>
2535
- </div>
2536
- <div class="actions">
2537
- <button mat-icon-button (click)="editWidget(w)" [disabled]="!canEditWidget(w)" [matTooltip]="tx('editor.steps.editComponent', 'Edit component')">
2538
- <mat-icon [praxisIcon]="'tune'"></mat-icon>
2539
- </button>
2540
- <button mat-icon-button color="warn" (click)="removeAdvancedWidget(w)" [matTooltip]="tx('editor.steps.removeComponent', 'Remove component')">
2541
- <mat-icon [praxisIcon]="'delete'"></mat-icon>
2542
- </button>
2510
+ <div class="section-body">
2511
+ <div class="cta-grid">
2512
+ <div class="cta-row-item">
2513
+ <div class="cta-head">
2514
+ <mat-icon [praxisIcon]="'account_tree'"></mat-icon>
2515
+ <div>
2516
+ <div class="cta-title">{{ tx('editor.steps.treeListTitle', 'Tree list') }}</div>
2517
+ <div class="cta-desc">{{ tx('editor.steps.treeListDesc', 'Hierarchical data with simple selection.') }}</div>
2518
+ </div>
2519
+ </div>
2520
+ <div class="cta-actions">
2521
+ <button mat-stroked-button (click)="addTreeList()">
2522
+ <mat-icon [praxisIcon]="'add'"></mat-icon>
2523
+ {{ tx('editor.steps.insertTree', 'Insert tree') }}
2524
+ </button>
2525
+ </div>
2526
+ </div>
2527
+ <div class="cta-row-item">
2528
+ <div class="cta-head">
2529
+ <mat-icon [praxisIcon]="'swap_horiz'"></mat-icon>
2530
+ <div>
2531
+ <div class="cta-title">{{ tx('editor.steps.transferTitle', 'Item transfer') }}</div>
2532
+ <div class="cta-desc">{{ tx('editor.steps.transferDesc', 'Move items between lists for multi-selection.') }}</div>
2533
+ </div>
2534
+ </div>
2535
+ <div class="cta-actions">
2536
+ <button mat-stroked-button (click)="addTransferListQuick()">
2537
+ <mat-icon [praxisIcon]="'add'"></mat-icon>
2538
+ {{ tx('editor.steps.insertTransfer', 'Insert transfer') }}
2539
+ </button>
2540
+ </div>
2541
+ </div>
2542
+ <div class="cta-row-item">
2543
+ <div class="cta-head">
2544
+ <mat-icon [praxisIcon]="'search'"></mat-icon>
2545
+ <div>
2546
+ <div class="cta-title">{{ tx('editor.steps.searchTitle', 'Searchable selection') }}</div>
2547
+ <div class="cta-desc">{{ tx('editor.steps.searchDesc', 'Selection with local or remote search.') }}</div>
2548
+ </div>
2549
+ </div>
2550
+ <div class="cta-actions">
2551
+ <button mat-stroked-button (click)="addSearchableSelect()">
2552
+ <mat-icon [praxisIcon]="'add'"></mat-icon>
2553
+ {{ tx('editor.steps.insertSelector', 'Insert selector') }}
2554
+ </button>
2555
+ </div>
2556
+ </div>
2557
+ <div class="cta-row-item">
2558
+ <div class="cta-head">
2559
+ <mat-icon [praxisIcon]="'upload_file'"></mat-icon>
2560
+ <div>
2561
+ <div class="cta-title">{{ tx('editor.steps.uploadTitle', 'File upload') }}</div>
2562
+ <div class="cta-desc">{{ tx('editor.steps.uploadDesc', 'Attachments with validation and upload flow.') }}</div>
2563
+ </div>
2564
+ </div>
2565
+ <div class="cta-actions">
2566
+ <button mat-stroked-button (click)="addFilesUpload()">
2567
+ <mat-icon [praxisIcon]="'add'"></mat-icon>
2568
+ {{ tx('editor.steps.insertUpload', 'Insert upload') }}
2569
+ </button>
2570
+ </div>
2571
+ </div>
2572
+ </div>
2573
+ <div class="widget-list advanced-list">
2574
+ @for (w of advancedWidgets(step); track w) {
2575
+ <div class="widget-item">
2576
+ <div class="drag-handle"><mat-icon [praxisIcon]="'extension'"></mat-icon></div>
2577
+ <div class="info">
2578
+ <div class="name">{{ displayWidgetName(w) }}</div>
2579
+ <div class="sub">{{ w.id }}</div>
2580
+ </div>
2581
+ <div class="actions">
2582
+ <button mat-icon-button (click)="editWidget(w)" [disabled]="!canEditWidget(w)" [matTooltip]="tx('editor.steps.editComponent', 'Edit component')">
2583
+ <mat-icon [praxisIcon]="'tune'"></mat-icon>
2584
+ </button>
2585
+ <button mat-icon-button color="warn" (click)="removeAdvancedWidget(w)" [matTooltip]="tx('editor.steps.removeComponent', 'Remove component')">
2586
+ <mat-icon [praxisIcon]="'delete'"></mat-icon>
2587
+ </button>
2588
+ </div>
2589
+ </div>
2590
+ }
2591
+ @if (!advancedWidgets(step).length) {
2592
+ <div class="empty">{{ tx('editor.steps.emptyAdvanced', 'No advanced components added.') }}</div>
2593
+ }
2594
+ </div>
2543
2595
  </div>
2544
2596
  </div>
2545
- <div class="empty" *ngIf="!advancedWidgets(step).length">{{ tx('editor.steps.emptyAdvanced', 'No advanced components added.') }}</div>
2546
2597
  </div>
2547
2598
  </div>
2548
2599
  </div>
2549
- </div>
2550
- </div>
2551
- </div>
2552
- </div>
2553
- <ng-template #noSteps>
2554
- <div class="muted">{{ tx('editor.steps.noSteps', 'No steps defined.') }}</div>
2555
- </ng-template>
2556
- </div>
2600
+ } @else {
2601
+ <div class="muted">{{ tx('editor.steps.noSteps', 'No steps defined.') }}</div>
2602
+ }
2603
+ </div>
2604
+ </div>
2557
2605
  </mat-tab>
2558
-
2606
+
2559
2607
  <mat-tab [label]="tx('editor.navigation.tab', 'Navigation')">
2560
2608
  <div class="tab-pad">
2561
2609
  <div class="editor-intro">
@@ -2624,22 +2672,30 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
2624
2672
  <div class="inline-action-item">
2625
2673
  <div class="section-title">{{ tx('editor.navigation.prevIcon', 'Back icon') }}</div>
2626
2674
  <button mat-stroked-button type="button" (click)="pickNavIcon('prevIcon')" [disabled]="!navigationCfg.visible" [attr.aria-label]="tx('editor.navigation.pickPrevIcon', 'Choose the Back button icon')">
2627
- <mat-icon *ngIf="navigationCfg.prevIcon" [fontIcon]="navigationCfg.prevIcon"></mat-icon>
2628
- <ng-container *ngIf="!navigationCfg.prevIcon">{{ tx('editor.shared.pick', 'Choose') }}</ng-container>
2675
+ @if (navigationCfg.prevIcon) {
2676
+ <mat-icon [fontIcon]="navigationCfg.prevIcon"></mat-icon>
2677
+ }
2678
+ @if (!navigationCfg.prevIcon) {
2679
+ {{ tx('editor.shared.pick', 'Choose') }}
2680
+ }
2629
2681
  </button>
2630
2682
  </div>
2631
2683
  <div class="inline-action-item">
2632
2684
  <div class="section-title">{{ tx('editor.navigation.nextIcon', 'Next icon') }}</div>
2633
2685
  <button mat-stroked-button type="button" (click)="pickNavIcon('nextIcon')" [disabled]="!navigationCfg.visible" [attr.aria-label]="tx('editor.navigation.pickNextIcon', 'Choose the Next button icon')">
2634
- <mat-icon *ngIf="navigationCfg.nextIcon" [fontIcon]="navigationCfg.nextIcon"></mat-icon>
2635
- <ng-container *ngIf="!navigationCfg.nextIcon">{{ tx('editor.shared.pick', 'Choose') }}</ng-container>
2686
+ @if (navigationCfg.nextIcon) {
2687
+ <mat-icon [fontIcon]="navigationCfg.nextIcon"></mat-icon>
2688
+ }
2689
+ @if (!navigationCfg.nextIcon) {
2690
+ {{ tx('editor.shared.pick', 'Choose') }}
2691
+ }
2636
2692
  </button>
2637
2693
  </div>
2638
2694
  </div>
2639
2695
  </div>
2640
2696
  </div>
2641
2697
  </mat-tab>
2642
-
2698
+
2643
2699
  <mat-tab [label]="tx('editor.appearance.tab', 'Appearance')">
2644
2700
  <div class="tab-pad">
2645
2701
  <div class="editor-intro">
@@ -2691,38 +2747,52 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
2691
2747
  <div class="inline-action-item">
2692
2748
  <div class="section-title">{{ tx('editor.appearance.iconNumber', 'Number icon') }}</div>
2693
2749
  <button mat-stroked-button type="button" (click)="pickIcon('number')" [attr.aria-label]="tx('editor.appearance.pickIconNumber', 'Choose the number icon')">
2694
- <mat-icon *ngIf="icons.number; else pick" [fontIcon]="icons.number"></mat-icon>
2695
- <ng-template #pick>{{ tx('editor.shared.pick', 'Choose') }}</ng-template>
2750
+ @if (icons.number) {
2751
+ <mat-icon [fontIcon]="icons.number"></mat-icon>
2752
+ } @else {
2753
+ {{ tx('editor.shared.pick', 'Choose') }}
2754
+ }
2696
2755
  </button>
2697
2756
  </div>
2698
2757
  <div class="inline-action-item">
2699
2758
  <div class="section-title">{{ tx('editor.appearance.iconDone', 'Completed icon') }}</div>
2700
2759
  <button mat-stroked-button type="button" (click)="pickIcon('done')" [attr.aria-label]="tx('editor.appearance.pickIconDone', 'Choose the completed icon')">
2701
- <mat-icon *ngIf="icons.done; else pick2" [fontIcon]="icons.done"></mat-icon>
2702
- <ng-template #pick2>{{ tx('editor.shared.pick', 'Choose') }}</ng-template>
2760
+ @if (icons.done) {
2761
+ <mat-icon [fontIcon]="icons.done"></mat-icon>
2762
+ } @else {
2763
+ {{ tx('editor.shared.pick', 'Choose') }}
2764
+ }
2703
2765
  </button>
2704
2766
  </div>
2705
2767
  <div class="inline-action-item">
2706
2768
  <div class="section-title">{{ tx('editor.appearance.iconEdit', 'Edit icon') }}</div>
2707
2769
  <button mat-stroked-button type="button" (click)="pickIcon('edit')" [attr.aria-label]="tx('editor.appearance.pickIconEdit', 'Choose the edit icon')">
2708
- <mat-icon *ngIf="icons.edit; else pick3" [fontIcon]="icons.edit"></mat-icon>
2709
- <ng-template #pick3>{{ tx('editor.shared.pick', 'Choose') }}</ng-template>
2770
+ @if (icons.edit) {
2771
+ <mat-icon [fontIcon]="icons.edit"></mat-icon>
2772
+ } @else {
2773
+ {{ tx('editor.shared.pick', 'Choose') }}
2774
+ }
2710
2775
  </button>
2711
2776
  </div>
2712
2777
  <div class="inline-action-item">
2713
2778
  <div class="section-title">{{ tx('editor.appearance.iconError', 'Error icon') }}</div>
2714
2779
  <button mat-stroked-button type="button" (click)="pickIcon('error')" [attr.aria-label]="tx('editor.appearance.pickIconError', 'Choose the error icon')">
2715
- <mat-icon *ngIf="icons.error; else pick4" [fontIcon]="icons.error"></mat-icon>
2716
- <ng-template #pick4>{{ tx('editor.shared.pick', 'Choose') }}</ng-template>
2780
+ @if (icons.error) {
2781
+ <mat-icon [fontIcon]="icons.error"></mat-icon>
2782
+ } @else {
2783
+ {{ tx('editor.shared.pick', 'Choose') }}
2784
+ }
2717
2785
  </button>
2718
2786
  </div>
2719
2787
  </div>
2720
- <div class="icons-hint" *ngIf="symbolsLikelySelected.length && !appearance.iconsSet">
2721
- <div class="muted">
2722
- {{ tx('editor.appearance.symbolsHint', 'Hint: {{icons}} are Material Symbols icons. Select a Symbols set below or click').replace('{{icons}}', symbolsLikelySelected.join(', ')) }}
2723
- <button mat-button color="primary" type="button" (click)="setIconsSetToSymbols()">{{ tx('editor.appearance.useSymbols', 'Use Material Symbols (Outlined)') }}</button>.
2788
+ @if (symbolsLikelySelected.length && !appearance.iconsSet) {
2789
+ <div class="icons-hint">
2790
+ <div class="muted">
2791
+ {{ tx('editor.appearance.symbolsHint', 'Hint: {{icons}} are Material Symbols icons. Select a Symbols set below or click').replace('{{icons}}', symbolsLikelySelected.join(', ')) }}
2792
+ <button mat-button color="primary" type="button" (click)="setIconsSetToSymbols()">{{ tx('editor.appearance.useSymbols', 'Use Material Symbols (Outlined)') }}</button>.
2793
+ </div>
2724
2794
  </div>
2725
- </div>
2795
+ }
2726
2796
  <div class="pdx-appearance-actions">
2727
2797
  <button mat-stroked-button color="primary" type="button" (click)="applyPreset('neutral')">{{ tx('editor.appearance.presetNeutral', 'Preset: neutral') }}</button>
2728
2798
  <button mat-stroked-button color="primary" type="button" (click)="applyPreset('primary')">{{ tx('editor.appearance.presetPrimary', 'Preset: primary') }}</button>
@@ -2737,12 +2807,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
2737
2807
  </summary>
2738
2808
  <div class="disclosure-body">
2739
2809
  <div class="tokens-grid">
2740
- <div class="token-item" *ngFor="let key of stepperTokenKeys">
2741
- <mat-form-field appearance="outline" class="w-full">
2742
- <mat-label>{{ key }}</mat-label>
2743
- <input matInput [ngModel]="appearance.tokens?.[key]" (ngModelChange)="onTokenChange(key, $event)" [placeholder]="tx('editor.appearance.tokenPlaceholder', 'CSS value or var(--token)')" />
2744
- </mat-form-field>
2745
- </div>
2810
+ @for (key of stepperTokenKeys; track key) {
2811
+ <div class="token-item">
2812
+ <mat-form-field appearance="outline" class="w-full">
2813
+ <mat-label>{{ key }}</mat-label>
2814
+ <input matInput [ngModel]="appearance.tokens?.[key]" (ngModelChange)="onTokenChange(key, $event)" [placeholder]="tx('editor.appearance.tokenPlaceholder', 'CSS value or var(--token)')" />
2815
+ </mat-form-field>
2816
+ </div>
2817
+ }
2746
2818
  </div>
2747
2819
  <div class="code-card">
2748
2820
  <div class="code-head">{{ tx('editor.appearance.scssSnippet', 'SCSS snippet') }}</div>
@@ -2754,7 +2826,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
2754
2826
  </mat-tab>
2755
2827
  </mat-tab-group>
2756
2828
  </div>
2757
- `, styles: [".pdx-editor{display:grid;gap:16px}.pdx-editor .mat-mdc-form-field{width:100%}.pdx-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:12px}.pdx-toggles{display:flex;gap:12px;flex-wrap:wrap}.tab-pad{padding:16px;display:grid;gap:16px;background:var(--md-sys-color-surface);border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 78%,transparent);border-radius:16px}.help{color:var(--md-sys-color-on-surface-variant);font-size:13px}.editor-intro{display:flex;justify-content:space-between;gap:16px;align-items:flex-start;padding:4px 2px 2px}.editor-intro-copy{display:grid;gap:6px;max-width:760px}.eyebrow{font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--md-sys-color-on-surface-variant);font-weight:600}.editor-title{font-size:22px;line-height:1.15;font-weight:650;color:var(--md-sys-color-on-surface)}.editor-subtitle{max-width:72ch;color:var(--md-sys-color-on-surface-variant);line-height:1.45;font-size:14px}.editor-intro-meta{display:flex;gap:8px;align-items:flex-start}.meta-pill{display:grid;gap:2px;min-width:88px;padding:10px 12px;border-radius:14px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 70%,transparent);background:var(--md-sys-color-surface-container-low)}.meta-label{font-size:11px;text-transform:uppercase;letter-spacing:.06em;color:var(--md-sys-color-on-surface-variant)}.quick-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:12px;margin-bottom:6px}.icons-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:12px;margin:8px 0}.icon-item{display:grid;gap:6px;align-content:start}.icons-hint{margin-top:4px}.settings-group{display:grid;gap:14px;padding:2px 0 4px}.settings-group+.settings-group,.settings-group+.disclosure,.disclosure+.settings-group{padding-top:18px;border-top:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 60%,transparent)}.group-head{display:grid;gap:4px;max-width:72ch}.inline-actions-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:12px;align-items:start}.inline-action-item{display:grid;gap:8px;align-content:start;min-width:0}.pdx-steps{display:grid;gap:12px;padding:4px 0 2px}.steps-workspace{display:grid;grid-template-columns:minmax(260px,320px) minmax(0,1fr);gap:24px;align-items:start}.pdx-steps-header{display:flex;justify-content:space-between;align-items:center;gap:16px}.pdx-step-list{display:grid;gap:10px}.pdx-step-item{display:grid;grid-template-columns:20px 1fr auto;gap:10px;align-items:start;padding:12px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 68%,transparent);border-radius:14px;background:var(--md-sys-color-surface);cursor:pointer;outline:none}.pdx-step-item.active{border-color:color-mix(in srgb,var(--md-sys-color-primary) 55%,var(--md-sys-color-outline-variant));background:color-mix(in srgb,var(--md-sys-color-primary-container) 26%,var(--md-sys-color-surface));box-shadow:none}.pdx-step-item:focus-visible{border-color:var(--md-sys-color-primary);box-shadow:0 0 0 2px color-mix(in srgb,var(--md-sys-color-primary) 22%,transparent)}.drag-handle{display:flex;align-items:center;color:var(--md-sys-color-on-surface-variant)}.step-summary{display:grid;gap:8px;min-width:0}.step-summary-head{display:grid;gap:2px}.step-summary-index{font-size:11px;text-transform:uppercase;letter-spacing:.06em;color:var(--md-sys-color-on-surface-variant);font-weight:600}.step-summary-title{font-size:15px;line-height:1.3;font-weight:600;color:var(--md-sys-color-on-surface)}.step-summary-sub{font-size:12px;color:var(--md-sys-color-on-surface-variant);font-family:var(--md-ref-typeface-plain, monospace);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.step-summary-flags{display:flex;gap:6px;flex-wrap:wrap}.summary-chip{display:inline-flex;align-items:center;min-height:22px;padding:0 8px;border-radius:999px;background:var(--md-sys-color-surface-container-high);color:var(--md-sys-color-on-surface-variant);font-size:11px;font-weight:600}.summary-chip-warn{background:color-mix(in srgb,var(--md-sys-color-error-container) 60%,transparent);color:var(--md-sys-color-on-error-container)}.pdx-active-step{display:grid;gap:18px;min-width:0}.pdx-active-step .hdr{display:flex;gap:12px;align-items:flex-start;justify-content:space-between}.active-step-head{display:grid;gap:4px}.pdx-content-editor{display:grid;gap:16px}.section{display:grid;gap:12px;padding:0;border:none;border-radius:0;background:transparent}.section-body{display:grid;gap:12px}.section-title{font-weight:600;font-size:15px;color:var(--md-sys-color-on-surface)}.section-subtitle{font-size:13px;color:var(--md-sys-color-on-surface-variant);line-height:1.45}.section-head{display:flex;gap:12px;align-items:center;justify-content:space-between;flex-wrap:wrap}.editorial-section{padding-bottom:6px;border-bottom:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 68%,transparent)}.detail-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}.field-span-2{grid-column:span 2}.toggle-group{display:flex;gap:10px;flex-wrap:wrap;padding-top:4px}.disclosure{padding:0 0 12px;border-bottom:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 62%,transparent)}.disclosure summary{list-style:none;display:flex;justify-content:space-between;align-items:baseline;gap:16px;cursor:pointer;padding:0;position:relative}.disclosure summary::-webkit-details-marker{display:none}.disclosure summary:after{content:\"expand_more\";font-family:Material Icons;font-size:18px;color:var(--md-sys-color-on-surface-variant);transition:transform .16s ease}.disclosure[open] summary:after{transform:rotate(180deg)}.disclosure summary:focus-visible{outline:2px solid color-mix(in srgb,var(--md-sys-color-primary) 58%,transparent);outline-offset:4px;border-radius:8px}.disclosure-body{padding-top:12px}.widget-list{display:grid;gap:8px}.widget-item{display:grid;grid-template-columns:20px 1fr auto;align-items:start;gap:12px;padding:10px 0;border:none;border-radius:0;background:transparent;border-bottom:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 56%,transparent)}.widget-item .info{display:grid;gap:2px;min-width:0}.widget-item .info .name{font-weight:600}.widget-item .info .sub{font-size:12px;color:var(--md-sys-color-on-surface-variant);line-height:1.45}.widget-item .info .meta{margin-top:2px;font-size:11px;color:var(--md-sys-color-on-surface-variant);font-family:var(--md-ref-typeface-plain, monospace);opacity:.85}.widget-item .actions{display:flex;gap:2px;flex-wrap:nowrap;justify-content:flex-end;align-items:flex-start;opacity:.92}.editorial-item{align-items:start}.editorial-item .actions{justify-content:flex-end}.cta-row{display:flex;gap:8px;align-items:center}.spacer{flex:1 1 auto}.muted{color:var(--md-sys-color-on-surface-variant)}.cta-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:8px;margin-bottom:4px}.cta-row-item{display:grid;gap:10px;padding:12px 0;border-bottom:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 56%,transparent)}.tokens-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:12px;margin:8px 0}.token-item{display:contents}.pdx-appearance{margin-top:8px;display:grid;gap:8px}.pdx-appearance-actions{display:flex;gap:8px;flex-wrap:wrap}.zone-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:12px}.zone-column{display:grid;gap:10px;min-width:0}.zone-head{display:flex;align-items:center;justify-content:space-between;gap:8px}.zone-actions{display:flex;align-items:center;gap:8px;flex-wrap:wrap;justify-content:flex-end}.zone-title{font-weight:600}.zone-column+.zone-column{padding-left:16px;border-left:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 56%,transparent)}.zone-count{font-size:12px;padding:2px 8px;border-radius:999px;background:var(--md-sys-color-surface-container-high);color:var(--md-sys-color-on-surface)}.advanced-list{margin-top:4px}.form-row-card{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:10px 0;border-bottom:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 56%,transparent)}.form-row-main{display:flex;align-items:center;gap:12px;min-width:0}.form-row-actions{display:flex;gap:4px;flex-wrap:wrap;justify-content:flex-end}.code-card{margin-top:8px}.code-head{font-weight:600;margin-bottom:4px}.code{white-space:pre;overflow:auto;background:var(--md-sys-color-surface-container-highest)}.w-full{grid-column:1 / -1}.min-180{min-width:180px}.help-icon-button{--mdc-icon-button-state-layer-size: 28px;--mdc-icon-button-icon-size: 18px;width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;margin-right:-4px}.help-icon-button mat-icon{font-size:18px;width:18px;height:18px}.mat-mdc-form-field-icon-suffix{align-self:center}.cta-row-item .cta-head{display:grid;grid-template-columns:20px 1fr;align-items:start;gap:10px}.cta-row-item .cta-title{font-weight:600;color:var(--md-sys-color-on-surface)}.cta-row-item .cta-desc{font-size:12px;color:var(--md-sys-color-on-surface-variant);line-height:1.45;margin-top:2px}.cta-row-item .cta-actions{display:flex;gap:8px;align-items:center}.widget-item:last-child,.cta-row-item:last-child,.form-row-card:last-child{border-bottom:none}@media(max-width:900px){.editor-intro{flex-direction:column}.steps-workspace{grid-template-columns:1fr;gap:20px}.pdx-step-item{grid-template-columns:20px 1fr}.pdx-actions{grid-column:1 / -1;justify-self:end}.widget-item{grid-template-columns:20px 1fr}.widget-item .actions{grid-column:1 / -1;justify-content:flex-end}.form-row-card{flex-direction:column;align-items:flex-start}.form-row-actions{justify-content:flex-start}.zone-column+.zone-column{padding-left:0;border-left:none;padding-top:12px;border-top:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 56%,transparent)}}@media(max-width:640px){.tab-pad{padding:14px}.editor-title{font-size:20px}.pdx-active-step .hdr{align-items:flex-start;flex-direction:column}.detail-grid{grid-template-columns:1fr}.field-span-2{grid-column:auto}.toggle-group{flex-direction:column;align-items:flex-start}.zone-head{align-items:flex-start;flex-direction:column}.zone-actions,.widget-item .actions{justify-content:flex-start}.disclosure summary{flex-direction:column;align-items:flex-start}}\n"] }]
2829
+ `, styles: [".pdx-editor{display:grid;gap:16px}.pdx-editor .mat-mdc-form-field{width:100%}.pdx-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:12px}.pdx-toggles{display:flex;gap:12px;flex-wrap:wrap}.tab-pad{padding:16px;display:grid;gap:16px;background:var(--md-sys-color-surface);border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 78%,transparent);border-radius:16px}.help{color:var(--md-sys-color-on-surface-variant);font-size:13px}.editor-intro{display:flex;justify-content:space-between;gap:16px;align-items:flex-start;padding:4px 2px 2px}.editor-intro-copy{display:grid;gap:6px;max-width:760px}.eyebrow{font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--md-sys-color-on-surface-variant);font-weight:600}.editor-title{font-size:22px;line-height:1.15;font-weight:650;color:var(--md-sys-color-on-surface)}.editor-subtitle{max-width:72ch;color:var(--md-sys-color-on-surface-variant);line-height:1.45;font-size:14px}.editor-intro-meta{display:flex;gap:8px;align-items:flex-start}.meta-pill{display:grid;gap:2px;min-width:88px;padding:10px 12px;border-radius:14px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 70%,transparent);background:var(--md-sys-color-surface-container-low)}.meta-label{font-size:11px;text-transform:uppercase;letter-spacing:.06em;color:var(--md-sys-color-on-surface-variant)}.quick-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:12px;margin-bottom:6px}.icons-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:12px;margin:8px 0}.icon-item{display:grid;gap:6px;align-content:start}.icons-hint{margin-top:4px}.settings-group{display:grid;gap:14px;padding:2px 0 4px}.settings-group+.settings-group,.settings-group+.disclosure,.disclosure+.settings-group{padding-top:18px;border-top:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 60%,transparent)}.group-head{display:grid;gap:4px;max-width:72ch}.inline-actions-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:12px;align-items:start}.inline-action-item{display:grid;gap:8px;align-content:start;min-width:0}.pdx-steps{display:grid;gap:12px;padding:4px 0 2px}.steps-workspace{display:grid;grid-template-columns:minmax(260px,320px) minmax(0,1fr);gap:24px;align-items:start}.pdx-steps-header{display:flex;justify-content:space-between;align-items:center;gap:16px}.pdx-step-list{display:grid;gap:10px}.pdx-step-item{display:grid;grid-template-columns:20px 1fr auto;gap:10px;align-items:start;padding:12px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 68%,transparent);border-radius:14px;background:var(--md-sys-color-surface);cursor:pointer;outline:none}.pdx-step-item.active{border-color:color-mix(in srgb,var(--md-sys-color-primary) 55%,var(--md-sys-color-outline-variant));background:color-mix(in srgb,var(--md-sys-color-primary-container) 26%,var(--md-sys-color-surface));box-shadow:none}.pdx-step-item:focus-visible{border-color:var(--md-sys-color-primary);box-shadow:0 0 0 2px color-mix(in srgb,var(--md-sys-color-primary) 22%,transparent)}.drag-handle{display:flex;align-items:center;color:var(--md-sys-color-on-surface-variant)}.step-summary{display:grid;gap:8px;min-width:0}.step-summary-head{display:grid;gap:2px}.step-summary-index{font-size:11px;text-transform:uppercase;letter-spacing:.06em;color:var(--md-sys-color-on-surface-variant);font-weight:600}.step-summary-title{font-size:15px;line-height:1.3;font-weight:600;color:var(--md-sys-color-on-surface)}.step-summary-sub{font-size:12px;color:var(--md-sys-color-on-surface-variant);font-family:var(--md-ref-typeface-plain, monospace);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.step-summary-flags{display:flex;gap:6px;flex-wrap:wrap}.summary-chip{display:inline-flex;align-items:center;min-height:22px;padding:0 8px;border-radius:999px;background:var(--md-sys-color-surface-container-high);color:var(--md-sys-color-on-surface-variant);font-size:11px;font-weight:600}.summary-chip-warn{background:color-mix(in srgb,var(--md-sys-color-error-container) 60%,transparent);color:var(--md-sys-color-on-error-container)}.pdx-active-step{display:grid;gap:18px;min-width:0}.pdx-active-step .hdr{display:flex;gap:12px;align-items:flex-start;justify-content:space-between}.active-step-head{display:grid;gap:4px}.pdx-content-editor{display:grid;gap:16px}.section{display:grid;gap:12px;padding:0;border:none;border-radius:0;background:transparent}.section-body{display:grid;gap:12px}.section-title{font-weight:600;font-size:15px;color:var(--md-sys-color-on-surface)}.section-subtitle{font-size:13px;color:var(--md-sys-color-on-surface-variant);line-height:1.45}.section-head{display:flex;gap:12px;align-items:center;justify-content:space-between;flex-wrap:wrap}.editorial-section{padding-bottom:6px;border-bottom:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 68%,transparent)}.detail-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}.field-span-2{grid-column:span 2}.toggle-group{display:flex;gap:10px;flex-wrap:wrap;padding-top:4px}.disclosure{padding:0 0 12px;border-bottom:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 62%,transparent)}.disclosure summary{list-style:none;display:flex;justify-content:space-between;align-items:baseline;gap:16px;cursor:pointer;padding:0;position:relative}.disclosure summary::-webkit-details-marker{display:none}.disclosure summary:after{content:\"expand_more\";font-family:Material Icons;font-size:18px;color:var(--md-sys-color-on-surface-variant);transition:transform .16s ease}.disclosure[open] summary:after{transform:rotate(180deg)}.disclosure summary:focus-visible{outline:2px solid color-mix(in srgb,var(--md-sys-color-primary) 58%,transparent);outline-offset:4px;border-radius:8px}.disclosure-body{padding-top:12px}.widget-list{display:grid;gap:8px}.widget-item{display:grid;grid-template-columns:20px 1fr auto;align-items:start;gap:12px;padding:10px 0;border:none;border-radius:0;background:transparent;border-bottom:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 56%,transparent)}.widget-item .info{display:grid;gap:2px;min-width:0}.widget-item .info .name{font-weight:600}.widget-item .info .sub{font-size:12px;color:var(--md-sys-color-on-surface-variant);line-height:1.45}.widget-item .info .meta{margin-top:2px;font-size:11px;color:var(--md-sys-color-on-surface-variant);font-family:var(--md-ref-typeface-plain, monospace);opacity:.85}.widget-item .actions{display:flex;gap:2px;flex-wrap:nowrap;justify-content:flex-end;align-items:flex-start;opacity:.92}.editorial-item{align-items:start}.editorial-item .actions{justify-content:flex-end}.cta-row{display:flex;gap:8px;align-items:center}.spacer{flex:1 1 auto}.muted{color:var(--md-sys-color-on-surface-variant)}.cta-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:8px;margin-bottom:4px}.cta-row-item{display:grid;gap:10px;padding:12px 0;border-bottom:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 56%,transparent)}.tokens-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:12px;margin:8px 0}.token-item{display:contents}.pdx-appearance{margin-top:8px;display:grid;gap:8px}.pdx-appearance-actions{display:flex;gap:8px;flex-wrap:wrap}.zone-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:12px}.zone-column{display:grid;gap:10px;min-width:0}.zone-head{display:flex;align-items:center;justify-content:space-between;gap:8px}.zone-actions{display:flex;align-items:center;gap:8px;flex-wrap:wrap;justify-content:flex-end}.zone-title{font-weight:600}.zone-column+.zone-column{padding-left:16px;border-left:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 56%,transparent)}.zone-count{font-size:12px;padding:2px 8px;border-radius:999px;background:var(--md-sys-color-surface-container-high);color:var(--md-sys-color-on-surface)}.advanced-list{margin-top:4px}.form-row-card{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:10px 0;border-bottom:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 56%,transparent)}.form-row-main{display:flex;align-items:center;gap:12px;min-width:0}.form-row-actions{display:flex;gap:4px;flex-wrap:wrap;justify-content:flex-end}.code-card{margin-top:8px}.code-head{font-weight:600;margin-bottom:4px}.code{white-space:pre;overflow:auto;background:var(--md-sys-color-surface-container-highest)}.w-full{grid-column:1 / -1}.min-180{min-width:180px}.help-icon-button{--mdc-icon-button-state-layer-size: 28px;--mdc-icon-button-icon-size: 18px;width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;margin-right:-4px}.help-icon-button mat-icon{font-size:18px;width:18px;height:18px}.mat-mdc-form-field-icon-suffix{align-self:center}.cta-row-item .cta-head{display:grid;grid-template-columns:20px 1fr;align-items:start;gap:10px}.cta-row-item .cta-title{font-weight:600;color:var(--md-sys-color-on-surface)}.cta-row-item .cta-desc{font-size:12px;color:var(--md-sys-color-on-surface-variant);line-height:1.45;margin-top:2px}.cta-row-item .cta-actions{display:flex;gap:8px;align-items:center}.widget-item:last-child,.cta-row-item:last-child,.form-row-card:last-child{border-bottom:none}@media(max-width:900px){.editor-intro{flex-direction:column}.steps-workspace{grid-template-columns:1fr;gap:20px}.pdx-step-item{grid-template-columns:20px 1fr}.pdx-actions{grid-column:1 / -1;justify-self:end}.widget-item{grid-template-columns:20px 1fr}.widget-item .actions{grid-column:1 / -1;justify-content:flex-end}.form-row-card{flex-direction:column;align-items:flex-start}.form-row-actions{justify-content:flex-start}.zone-column+.zone-column{padding-left:0;border-left:none;padding-top:12px;border-top:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 56%,transparent)}}@media(max-width:640px){.tab-pad{padding:14px}.editor-title{font-size:20px}.pdx-active-step .hdr{align-items:flex-start;flex-direction:column}.detail-grid{grid-template-columns:1fr}.field-span-2{grid-column:auto}.toggle-group{flex-direction:column;align-items:flex-start}.zone-head{align-items:flex-start;flex-direction:column}.zone-actions,.widget-item .actions{justify-content:flex-start}.disclosure summary{flex-direction:column;align-items:flex-start}}\n"] }]
2758
2830
  }], ctorParameters: () => [{ type: undefined, decorators: [{
2759
2831
  type: Inject,
2760
2832
  args: [SETTINGS_PANEL_DATA]
@@ -3278,8 +3350,8 @@ class PraxisStepper {
3278
3350
  // Templates projetados
3279
3351
  stepLabelTpl;
3280
3352
  // Dados e estado
3281
- _config = signal(null, ...(ngDevMode ? [{ debugName: "_config" }] : []));
3282
- _selectedIndex = signal(0, ...(ngDevMode ? [{ debugName: "_selectedIndex" }] : []));
3353
+ _config = signal(null, ...(ngDevMode ? [{ debugName: "_config" }] : /* istanbul ignore next */ []));
3354
+ _selectedIndex = signal(0, ...(ngDevMode ? [{ debugName: "_selectedIndex" }] : /* istanbul ignore next */ []));
3283
3355
  _formGroups = new Map();
3284
3356
  _formValidity = new Map();
3285
3357
  hostElement = inject((ElementRef));
@@ -3356,7 +3428,7 @@ class PraxisStepper {
3356
3428
  if (!this.aiAssistantOpen) {
3357
3429
  this.openAiAssistantFromSession(session);
3358
3430
  }
3359
- }, ...(ngDevMode ? [{ debugName: "aiAssistantSessionEffect" }] : []));
3431
+ }, ...(ngDevMode ? [{ debugName: "aiAssistantSessionEffect" }] : /* istanbul ignore next */ []));
3360
3432
  warnedMissingId = false;
3361
3433
  emptyStepRichContentDocument = createEmptyRichContentDocument();
3362
3434
  animationDone = new EventEmitter();
@@ -3377,19 +3449,19 @@ class PraxisStepper {
3377
3449
  aiAssistantController = null;
3378
3450
  aiAssistantStateSubscription = null;
3379
3451
  // Computed getters
3380
- steps = computed(() => this._config()?.steps || [], ...(ngDevMode ? [{ debugName: "steps" }] : []));
3381
- orientation = computed(() => this._config()?.orientation || 'horizontal', ...(ngDevMode ? [{ debugName: "orientation" }] : []));
3382
- headerPosition = computed(() => this._config()?.headerPosition || 'top', ...(ngDevMode ? [{ debugName: "headerPosition" }] : []));
3452
+ steps = computed(() => this._config()?.steps || [], ...(ngDevMode ? [{ debugName: "steps" }] : /* istanbul ignore next */ []));
3453
+ orientation = computed(() => this._config()?.orientation || 'horizontal', ...(ngDevMode ? [{ debugName: "orientation" }] : /* istanbul ignore next */ []));
3454
+ headerPosition = computed(() => this._config()?.headerPosition || 'top', ...(ngDevMode ? [{ debugName: "headerPosition" }] : /* istanbul ignore next */ []));
3383
3455
  // labelPosition: default 'end' no Material
3384
- labelPos = computed(() => this._config()?.labelPosition ?? this.labelPosition ?? 'end', ...(ngDevMode ? [{ debugName: "labelPos" }] : []));
3385
- linear = computed(() => !!this._config()?.linear, ...(ngDevMode ? [{ debugName: "linear" }] : []));
3386
- disableRipple = computed(() => this._config()?.disableRipple ?? this.disableRippleInput, ...(ngDevMode ? [{ debugName: "disableRipple" }] : []));
3387
- animationDuration = computed(() => this._config()?.animationDuration || '300ms', ...(ngDevMode ? [{ debugName: "animationDuration" }] : []));
3388
- stepperColor = computed(() => this._config()?.color ?? this.color, ...(ngDevMode ? [{ debugName: "stepperColor" }] : []));
3389
- icons = computed(() => this._config()?.appearance?.icons, ...(ngDevMode ? [{ debugName: "icons" }] : []));
3390
- iconsSet = computed(() => this._config()?.appearance?.iconsSet, ...(ngDevMode ? [{ debugName: "iconsSet" }] : []));
3456
+ labelPos = computed(() => this._config()?.labelPosition ?? this.labelPosition ?? 'end', ...(ngDevMode ? [{ debugName: "labelPos" }] : /* istanbul ignore next */ []));
3457
+ linear = computed(() => !!this._config()?.linear, ...(ngDevMode ? [{ debugName: "linear" }] : /* istanbul ignore next */ []));
3458
+ disableRipple = computed(() => this._config()?.disableRipple ?? this.disableRippleInput, ...(ngDevMode ? [{ debugName: "disableRipple" }] : /* istanbul ignore next */ []));
3459
+ animationDuration = computed(() => this._config()?.animationDuration || '300ms', ...(ngDevMode ? [{ debugName: "animationDuration" }] : /* istanbul ignore next */ []));
3460
+ stepperColor = computed(() => this._config()?.color ?? this.color, ...(ngDevMode ? [{ debugName: "stepperColor" }] : /* istanbul ignore next */ []));
3461
+ icons = computed(() => this._config()?.appearance?.icons, ...(ngDevMode ? [{ debugName: "icons" }] : /* istanbul ignore next */ []));
3462
+ iconsSet = computed(() => this._config()?.appearance?.iconsSet, ...(ngDevMode ? [{ debugName: "iconsSet" }] : /* istanbul ignore next */ []));
3391
3463
  // Navigation helpers
3392
- nav = computed(() => this._config()?.navigation || {}, ...(ngDevMode ? [{ debugName: "nav" }] : []));
3464
+ nav = computed(() => this._config()?.navigation || {}, ...(ngDevMode ? [{ debugName: "nav" }] : /* istanbul ignore next */ []));
3393
3465
  navVisible = () => this.nav()?.visible !== false; // default true
3394
3466
  navVariant = () => (this.nav()?.variant || 'raised');
3395
3467
  navColor = () => (this.nav()?.color || 'primary');
@@ -3431,7 +3503,7 @@ class PraxisStepper {
3431
3503
  return 0;
3432
3504
  return Math.min(Math.max(0, idx), max);
3433
3505
  }
3434
- selectedIndexComputed = computed(() => this.clampIndex(this._selectedIndex()), ...(ngDevMode ? [{ debugName: "selectedIndexComputed" }] : []));
3506
+ selectedIndexComputed = computed(() => this.clampIndex(this._selectedIndex()), ...(ngDevMode ? [{ debugName: "selectedIndexComputed" }] : /* istanbul ignore next */ []));
3435
3507
  densityClass = () => {
3436
3508
  const d = this._config()?.density;
3437
3509
  if (d === 'compact')
@@ -4043,184 +4115,238 @@ class PraxisStepper {
4043
4115
  resolveCssTokenName(name) {
4044
4116
  return name.startsWith('--') ? name : `--${name}`;
4045
4117
  }
4046
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisStepper, deps: [], target: i0.ɵɵFactoryTarget.Component });
4047
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.17", type: PraxisStepper, isStandalone: true, selector: "praxis-stepper", inputs: { stepperId: "stepperId", componentInstanceId: "componentInstanceId", config: "config", selectedIndexInput: "selectedIndexInput", selectedIndex: "selectedIndex", disableRippleInput: "disableRippleInput", enableCustomization: "enableCustomization", labelPosition: "labelPosition", color: "color", serverValidate: "serverValidate", stepperContext: "stepperContext" }, outputs: { selectedIndexChange: "selectedIndexChange", widgetEvent: "widgetEvent", stepFormReady: "stepFormReady", stepFormValueChange: "stepFormValueChange", animationDone: "animationDone", selectionChange: "selectionChange" }, host: { properties: { "class": "densityClass()" } }, queries: [{ propertyName: "stepLabelTpl", first: true, predicate: ["stepLabelTpl"], descendants: true, read: TemplateRef }], ngImport: i0, template: `
4048
- <div class="stepper-ai-assistant" *ngIf="enableCustomization">
4049
- <button
4050
- mat-mini-fab
4051
- color="primary"
4052
- type="button"
4053
- class="stepper-ai-assistant-trigger"
4054
- aria-label="Abrir copiloto semantico Praxis do stepper"
4055
- data-testid="praxis-stepper-ai-assistant-trigger"
4056
- (click)="openAiAssistant()"
4057
- >
4058
- <mat-icon [praxisIcon]="'auto_awesome'"></mat-icon>
4059
- </button>
4060
- </div>
4061
- <praxis-ai-assistant-shell
4062
- *ngIf="aiAssistantOpen && aiAssistantViewState"
4063
- [mode]="aiAssistantViewState.mode"
4064
- [state]="aiAssistantViewState.state"
4065
- [contextItems]="aiAssistantViewState.contextItems"
4066
- [attachments]="aiAssistantViewState.attachments"
4067
- [messages]="aiAssistantViewState.messages"
4068
- [quickReplies]="aiAssistantViewState.quickReplies"
4069
- [prompt]="aiAssistantPrompt"
4070
- [statusText]="aiAssistantViewState.statusText"
4071
- [errorText]="aiAssistantViewState.errorText"
4072
- [busy]="aiAssistantViewState.state === 'processing' || aiAssistantViewState.state === 'applying'"
4073
- [canApply]="aiAssistantViewState.canApply"
4074
- [labels]="aiAssistantLabels"
4075
- [layout]="aiAssistantLayout"
4076
- testIdPrefix="praxis-stepper-ai-assistant"
4077
- (promptChange)="onAiAssistantPromptChange($event)"
4078
- (submitPrompt)="onAiAssistantSubmit($event)"
4079
- (apply)="onAiAssistantApply()"
4080
- (retryTurn)="onAiAssistantRetry()"
4081
- (cancelTurn)="onAiAssistantCancel()"
4082
- (quickReply)="onAiAssistantQuickReply($event)"
4083
- (editMessage)="onAiAssistantEditMessage($event)"
4084
- (resendMessage)="onAiAssistantResendMessage($event)"
4085
- (layoutChange)="onAiAssistantLayoutChange($event)"
4086
- (close)="closeAiAssistant()"
4087
- ></praxis-ai-assistant-shell>
4088
- <ng-container *ngIf="steps().length > 0; else emptyState">
4089
- <mat-stepper
4090
- #stepperRoot
4091
- [linear]="linear()"
4092
- [orientation]="orientation()"
4093
- [headerPosition]="headerPosition()"
4094
- [labelPosition]="labelPos()"
4095
- [disableRipple]="disableRipple()"
4096
- [color]="stepperColor()"
4097
- [animationDuration]="animationDuration()"
4098
- [selectedIndex]="selectedIndexComputed()"
4099
- (selectionChange)="onSelectionChange($event)"
4100
- (animationDone)="onAnimationDone()"
4101
- [class]="stepperClassList()"
4102
- >
4103
- <!-- Projeção de ícones customizados do header: <ng-template matStepperIcon="done"> ... </ng-template> -->
4104
- <ng-content></ng-content>
4105
- <!-- Overrides de ícones via configuração (appearance.icons) -->
4106
- <ng-template *ngIf="icons()?.number as icn" matStepperIcon="number">
4107
- <mat-icon [praxisIcon]="icn"></mat-icon>
4108
- </ng-template>
4109
- <ng-template *ngIf="icons()?.done as icn" matStepperIcon="done">
4110
- <mat-icon [praxisIcon]="icn"></mat-icon>
4111
- </ng-template>
4112
- <ng-template *ngIf="icons()?.edit as icn" matStepperIcon="edit">
4113
- <mat-icon [praxisIcon]="icn"></mat-icon>
4114
- </ng-template>
4115
- <ng-template *ngIf="icons()?.error as icn" matStepperIcon="error">
4116
- <mat-icon [praxisIcon]="icn"></mat-icon>
4117
- </ng-template>
4118
- <mat-step *ngFor="let step of steps(); let i = index; trackBy: trackStep"
4119
- [stepControl]="$any(formGroupFor(i))"
4120
- [id]="step.id || ''"
4121
- [aria-label]="step.ariaLabel || ''"
4122
- [aria-labelledby]="step.ariaLabelledby || ''"
4123
- [label]="step.label"
4124
- [optional]="step.optional || false"
4125
- [editable]="step.editable ?? true"
4126
- [completed]="computedCompleted(i, step)"
4127
- [hasError]="computedHasError(i, step)"
4128
- [errorMessage]="step.errorMessage || ''"
4129
- [state]="step.state || step.stateIcon || ''"
4118
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisStepper, deps: [], target: i0.ɵɵFactoryTarget.Component });
4119
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PraxisStepper, isStandalone: true, selector: "praxis-stepper", inputs: { stepperId: "stepperId", componentInstanceId: "componentInstanceId", config: "config", selectedIndexInput: "selectedIndexInput", selectedIndex: "selectedIndex", disableRippleInput: "disableRippleInput", enableCustomization: "enableCustomization", labelPosition: "labelPosition", color: "color", serverValidate: "serverValidate", stepperContext: "stepperContext" }, outputs: { selectedIndexChange: "selectedIndexChange", widgetEvent: "widgetEvent", stepFormReady: "stepFormReady", stepFormValueChange: "stepFormValueChange", animationDone: "animationDone", selectionChange: "selectionChange" }, host: { properties: { "class": "densityClass()" } }, queries: [{ propertyName: "stepLabelTpl", first: true, predicate: ["stepLabelTpl"], descendants: true, read: TemplateRef }], ngImport: i0, template: `
4120
+ @if (enableCustomization) {
4121
+ <div class="stepper-ai-assistant">
4122
+ <button
4123
+ mat-mini-fab
4124
+ color="primary"
4125
+ type="button"
4126
+ class="stepper-ai-assistant-trigger"
4127
+ aria-label="Abrir copiloto semantico Praxis do stepper"
4128
+ data-testid="praxis-stepper-ai-assistant-trigger"
4129
+ (click)="openAiAssistant()"
4130
+ >
4131
+ <mat-icon [praxisIcon]="'auto_awesome'"></mat-icon>
4132
+ </button>
4133
+ </div>
4134
+ }
4135
+ @if (aiAssistantOpen && aiAssistantViewState) {
4136
+ <praxis-ai-assistant-shell
4137
+ [mode]="aiAssistantViewState.mode"
4138
+ [state]="aiAssistantViewState.state"
4139
+ [contextItems]="aiAssistantViewState.contextItems"
4140
+ [attachments]="aiAssistantViewState.attachments"
4141
+ [messages]="aiAssistantViewState.messages"
4142
+ [quickReplies]="aiAssistantViewState.quickReplies"
4143
+ [prompt]="aiAssistantPrompt"
4144
+ [statusText]="aiAssistantViewState.statusText"
4145
+ [errorText]="aiAssistantViewState.errorText"
4146
+ [busy]="aiAssistantViewState.state === 'processing' || aiAssistantViewState.state === 'applying'"
4147
+ [canApply]="aiAssistantViewState.canApply"
4148
+ [labels]="aiAssistantLabels"
4149
+ [layout]="aiAssistantLayout"
4150
+ testIdPrefix="praxis-stepper-ai-assistant"
4151
+ (promptChange)="onAiAssistantPromptChange($event)"
4152
+ (submitPrompt)="onAiAssistantSubmit($event)"
4153
+ (apply)="onAiAssistantApply()"
4154
+ (retryTurn)="onAiAssistantRetry()"
4155
+ (cancelTurn)="onAiAssistantCancel()"
4156
+ (quickReply)="onAiAssistantQuickReply($event)"
4157
+ (editMessage)="onAiAssistantEditMessage($event)"
4158
+ (resendMessage)="onAiAssistantResendMessage($event)"
4159
+ (layoutChange)="onAiAssistantLayoutChange($event)"
4160
+ (close)="closeAiAssistant()"
4161
+ ></praxis-ai-assistant-shell>
4162
+ }
4163
+ @if (steps().length > 0) {
4164
+ <mat-stepper
4165
+ #stepperRoot
4166
+ [linear]="linear()"
4167
+ [orientation]="orientation()"
4168
+ [headerPosition]="headerPosition()"
4169
+ [labelPosition]="labelPos()"
4170
+ [disableRipple]="disableRipple()"
4171
+ [color]="stepperColor()"
4172
+ [animationDuration]="animationDuration()"
4173
+ [selectedIndex]="selectedIndexComputed()"
4174
+ (selectionChange)="onSelectionChange($event)"
4175
+ (animationDone)="onAnimationDone()"
4176
+ [class]="stepperClassList()"
4130
4177
  >
4131
- <ng-template matStepLabel>
4132
- <ng-container *ngIf="stepLabelTpl; else plainLabel"
4133
- [ngTemplateOutlet]="stepLabelTpl"
4134
- [ngTemplateOutletContext]="{ $implicit: step, index: i }"
4135
- ></ng-container>
4136
- <ng-template #plainLabel>{{ step.label }}</ng-template>
4137
- </ng-template>
4138
- <div [class]="contentClassList()">
4139
- <praxis-rich-content
4140
- *ngIf="hasRichContent(step.stepBlocksBeforeForm)"
4141
- [document]="step.stepBlocksBeforeForm || emptyStepRichContentDocument"
4142
- [context]="getStepRichContentContext(i)"
4143
- rootClassName="pdx-step-rich-content pdx-step-rich-content--before"
4144
- ></praxis-rich-content>
4145
- <praxis-dynamic-form *ngIf="step.form as f"
4146
- [resourcePath]="f.resourcePath"
4147
- [resourceId]="$any(f.resourceId)"
4148
- [mode]="f.mode || 'create'"
4149
- [config]="f.config || { sections: [] }"
4150
- [schemaSource]="f.schemaSource || 'resource'"
4151
- [formId]="f.formId"
4152
- (formReady)="onFormReady(i, $event)"
4153
- (valueChange)="onFormValueChange(i, $event)"
4154
- ></praxis-dynamic-form>
4155
- <praxis-rich-content
4156
- *ngIf="hasRichContent(step.stepBlocksAfterForm)"
4157
- [document]="step.stepBlocksAfterForm || emptyStepRichContentDocument"
4158
- [context]="getStepRichContentContext(i)"
4159
- rootClassName="pdx-step-rich-content pdx-step-rich-content--after"
4160
- ></praxis-rich-content>
4161
- <ng-container *ngFor="let wd of step.widgets || []"
4162
- [dynamicWidgetLoader]="wd"
4163
- [context]="stepperContext"
4164
- [strictValidation]="true"
4165
- [autoWireOutputs]="true"
4166
- (widgetEvent)="onChildWidgetEvent(i, wd, $event)"></ng-container>
4167
- <ng-container *ngIf="isStepEmpty(step)">
4168
- <praxis-empty-state-card
4169
- [inline]="true"
4170
- icon="dashboard_customize"
4171
- title="Sem conteúdo nesta etapa"
4172
- description="Adicione um formulário ou widgets a esta etapa, ou abra o editor para configurar."
4173
- [primaryAction]="{ label: 'Abrir editor', icon: 'tune', action: openEditor.bind(this) }"
4174
- ></praxis-empty-state-card>
4175
- </ng-container>
4176
- </div>
4177
- <div *ngIf="navVisible()" [class]="navActionsClass()">
4178
- <!-- PREV button (hidden on first step) -->
4179
- <ng-container *ngIf="selectedIndexComputed() > 0">
4180
- <ng-container [ngSwitch]="navVariant()">
4181
- <button *ngSwitchCase="'flat'" mat-flat-button [color]="navColor()" type="button" (click)="onPrev()">
4182
- <mat-icon *ngIf="navPrevIcon() as ic" [praxisIcon]="ic"></mat-icon>
4183
- {{ navPrevLabel() }}
4184
- </button>
4185
- <button *ngSwitchCase="'stroked'" mat-stroked-button [color]="navColor()" type="button" (click)="onPrev()">
4186
- <mat-icon *ngIf="navPrevIcon() as ic" [praxisIcon]="ic"></mat-icon>
4187
- {{ navPrevLabel() }}
4188
- </button>
4189
- <button *ngSwitchCase="'raised'" mat-raised-button [color]="navColor()" type="button" (click)="onPrev()">
4190
- <mat-icon *ngIf="navPrevIcon() as ic" [praxisIcon]="ic"></mat-icon>
4191
- {{ navPrevLabel() }}
4192
- </button>
4193
- <button *ngSwitchDefault mat-button [color]="navColor()" type="button" (click)="onPrev()">
4194
- <mat-icon *ngIf="navPrevIcon() as ic" [praxisIcon]="ic"></mat-icon>
4195
- {{ navPrevLabel() }}
4196
- </button>
4197
- </ng-container>
4198
- </ng-container>
4199
-
4200
- <!-- NEXT button -->
4201
- <ng-container [ngSwitch]="navVariant()">
4202
- <button *ngSwitchCase="'flat'" mat-flat-button [color]="navColor()" type="button" (click)="onNext(i)" [disabled]="isNextDisabled(i)">
4203
- {{ navNextLabel() }}
4204
- <mat-icon *ngIf="navNextIcon() as ic" [praxisIcon]="ic"></mat-icon>
4205
- </button>
4206
- <button *ngSwitchCase="'stroked'" mat-stroked-button [color]="navColor()" type="button" (click)="onNext(i)" [disabled]="isNextDisabled(i)">
4207
- {{ navNextLabel() }}
4208
- <mat-icon *ngIf="navNextIcon() as ic" [praxisIcon]="ic"></mat-icon>
4209
- </button>
4210
- <button *ngSwitchCase="'raised'" mat-raised-button [color]="navColor()" type="button" (click)="onNext(i)" [disabled]="isNextDisabled(i)">
4211
- {{ navNextLabel() }}
4212
- <mat-icon *ngIf="navNextIcon() as ic" [praxisIcon]="ic"></mat-icon>
4213
- </button>
4214
- <button *ngSwitchDefault mat-button [color]="navColor()" type="button" (click)="onNext(i)" [disabled]="isNextDisabled(i)">
4215
- {{ navNextLabel() }}
4216
- <mat-icon *ngIf="navNextIcon() as ic" [praxisIcon]="ic"></mat-icon>
4217
- </button>
4218
- </ng-container>
4219
- </div>
4220
- </mat-step>
4221
- </mat-stepper>
4222
- </ng-container>
4223
- <ng-template #emptyState>
4178
+ <!-- Projeção de ícones customizados do header: <ng-template matStepperIcon="done"> ... </ng-template> -->
4179
+ <ng-content></ng-content>
4180
+ <!-- Overrides de ícones via configuração (appearance.icons) -->
4181
+ @if (icons()?.number; as icn) {
4182
+ <ng-template matStepperIcon="number">
4183
+ <mat-icon [praxisIcon]="icn"></mat-icon>
4184
+ </ng-template>
4185
+ }
4186
+ @if (icons()?.done; as icn) {
4187
+ <ng-template matStepperIcon="done">
4188
+ <mat-icon [praxisIcon]="icn"></mat-icon>
4189
+ </ng-template>
4190
+ }
4191
+ @if (icons()?.edit; as icn) {
4192
+ <ng-template matStepperIcon="edit">
4193
+ <mat-icon [praxisIcon]="icn"></mat-icon>
4194
+ </ng-template>
4195
+ }
4196
+ @if (icons()?.error; as icn) {
4197
+ <ng-template matStepperIcon="error">
4198
+ <mat-icon [praxisIcon]="icn"></mat-icon>
4199
+ </ng-template>
4200
+ }
4201
+ @for (step of steps(); track trackStep(i, step); let i = $index) {
4202
+ <mat-step
4203
+ [stepControl]="$any(formGroupFor(i))"
4204
+ [id]="step.id || ''"
4205
+ [aria-label]="step.ariaLabel || ''"
4206
+ [aria-labelledby]="step.ariaLabelledby || ''"
4207
+ [label]="step.label"
4208
+ [optional]="step.optional || false"
4209
+ [editable]="step.editable ?? true"
4210
+ [completed]="computedCompleted(i, step)"
4211
+ [hasError]="computedHasError(i, step)"
4212
+ [errorMessage]="step.errorMessage || ''"
4213
+ [state]="step.state || step.stateIcon || ''"
4214
+ >
4215
+ <ng-template matStepLabel>
4216
+ @if (stepLabelTpl) {
4217
+ <ng-container
4218
+ [ngTemplateOutlet]="stepLabelTpl"
4219
+ [ngTemplateOutletContext]="{ $implicit: step, index: i }"
4220
+ ></ng-container>
4221
+ } @else {
4222
+ {{ step.label }}
4223
+ }
4224
+ </ng-template>
4225
+ <div [class]="contentClassList()">
4226
+ @if (hasRichContent(step.stepBlocksBeforeForm)) {
4227
+ <praxis-rich-content
4228
+ [document]="step.stepBlocksBeforeForm || emptyStepRichContentDocument"
4229
+ [context]="getStepRichContentContext(i)"
4230
+ rootClassName="pdx-step-rich-content pdx-step-rich-content--before"
4231
+ ></praxis-rich-content>
4232
+ }
4233
+ @if (step.form; as f) {
4234
+ <praxis-dynamic-form
4235
+ [resourcePath]="f.resourcePath"
4236
+ [resourceId]="$any(f.resourceId)"
4237
+ [mode]="f.mode || 'create'"
4238
+ [config]="f.config || { sections: [] }"
4239
+ [schemaSource]="f.schemaSource || 'resource'"
4240
+ [formId]="f.formId"
4241
+ (formReady)="onFormReady(i, $event)"
4242
+ (valueChange)="onFormValueChange(i, $event)"
4243
+ ></praxis-dynamic-form>
4244
+ }
4245
+ @if (hasRichContent(step.stepBlocksAfterForm)) {
4246
+ <praxis-rich-content
4247
+ [document]="step.stepBlocksAfterForm || emptyStepRichContentDocument"
4248
+ [context]="getStepRichContentContext(i)"
4249
+ rootClassName="pdx-step-rich-content pdx-step-rich-content--after"
4250
+ ></praxis-rich-content>
4251
+ }
4252
+ @for (wd of step.widgets || []; track wd) {
4253
+ <ng-container
4254
+ [dynamicWidgetLoader]="wd"
4255
+ [context]="stepperContext"
4256
+ [strictValidation]="true"
4257
+ [autoWireOutputs]="true"
4258
+ (widgetEvent)="onChildWidgetEvent(i, wd, $event)"></ng-container>
4259
+ }
4260
+ @if (isStepEmpty(step)) {
4261
+ <praxis-empty-state-card
4262
+ [inline]="true"
4263
+ icon="dashboard_customize"
4264
+ title="Sem conteúdo nesta etapa"
4265
+ description="Adicione um formulário ou widgets a esta etapa, ou abra o editor para configurar."
4266
+ [primaryAction]="{ label: 'Abrir editor', icon: 'tune', action: openEditor.bind(this) }"
4267
+ ></praxis-empty-state-card>
4268
+ }
4269
+ </div>
4270
+ @if (navVisible()) {
4271
+ <div [class]="navActionsClass()">
4272
+ <!-- PREV button (hidden on first step) -->
4273
+ @if (selectedIndexComputed() > 0) {
4274
+ @switch (navVariant()) {
4275
+ @case ('flat') {
4276
+ <button mat-flat-button [color]="navColor()" type="button" (click)="onPrev()">
4277
+ @if (navPrevIcon(); as ic) {
4278
+ <mat-icon [praxisIcon]="ic"></mat-icon>
4279
+ }
4280
+ {{ navPrevLabel() }}
4281
+ </button>
4282
+ }
4283
+ @case ('stroked') {
4284
+ <button mat-stroked-button [color]="navColor()" type="button" (click)="onPrev()">
4285
+ @if (navPrevIcon(); as ic) {
4286
+ <mat-icon [praxisIcon]="ic"></mat-icon>
4287
+ }
4288
+ {{ navPrevLabel() }}
4289
+ </button>
4290
+ }
4291
+ @case ('raised') {
4292
+ <button mat-raised-button [color]="navColor()" type="button" (click)="onPrev()">
4293
+ @if (navPrevIcon(); as ic) {
4294
+ <mat-icon [praxisIcon]="ic"></mat-icon>
4295
+ }
4296
+ {{ navPrevLabel() }}
4297
+ </button>
4298
+ }
4299
+ @default {
4300
+ <button mat-button [color]="navColor()" type="button" (click)="onPrev()">
4301
+ @if (navPrevIcon(); as ic) {
4302
+ <mat-icon [praxisIcon]="ic"></mat-icon>
4303
+ }
4304
+ {{ navPrevLabel() }}
4305
+ </button>
4306
+ }
4307
+ }
4308
+ }
4309
+ <!-- NEXT button -->
4310
+ @switch (navVariant()) {
4311
+ @case ('flat') {
4312
+ <button mat-flat-button [color]="navColor()" type="button" (click)="onNext(i)" [disabled]="isNextDisabled(i)">
4313
+ {{ navNextLabel() }}
4314
+ @if (navNextIcon(); as ic) {
4315
+ <mat-icon [praxisIcon]="ic"></mat-icon>
4316
+ }
4317
+ </button>
4318
+ }
4319
+ @case ('stroked') {
4320
+ <button mat-stroked-button [color]="navColor()" type="button" (click)="onNext(i)" [disabled]="isNextDisabled(i)">
4321
+ {{ navNextLabel() }}
4322
+ @if (navNextIcon(); as ic) {
4323
+ <mat-icon [praxisIcon]="ic"></mat-icon>
4324
+ }
4325
+ </button>
4326
+ }
4327
+ @case ('raised') {
4328
+ <button mat-raised-button [color]="navColor()" type="button" (click)="onNext(i)" [disabled]="isNextDisabled(i)">
4329
+ {{ navNextLabel() }}
4330
+ @if (navNextIcon(); as ic) {
4331
+ <mat-icon [praxisIcon]="ic"></mat-icon>
4332
+ }
4333
+ </button>
4334
+ }
4335
+ @default {
4336
+ <button mat-button [color]="navColor()" type="button" (click)="onNext(i)" [disabled]="isNextDisabled(i)">
4337
+ {{ navNextLabel() }}
4338
+ @if (navNextIcon(); as ic) {
4339
+ <mat-icon [praxisIcon]="ic"></mat-icon>
4340
+ }
4341
+ </button>
4342
+ }
4343
+ }
4344
+ </div>
4345
+ }
4346
+ </mat-step>
4347
+ }
4348
+ </mat-stepper>
4349
+ } @else {
4224
4350
  <praxis-empty-state-card
4225
4351
  icon="view_timeline"
4226
4352
  [inline]="true"
@@ -4229,199 +4355,254 @@ class PraxisStepper {
4229
4355
  [primaryAction]="primaryCta"
4230
4356
  [secondaryActions]="secondaryCtas"
4231
4357
  ></praxis-empty-state-card>
4232
- </ng-template>
4233
- <button
4234
- *ngIf="enableCustomization"
4235
- mat-fab
4236
- class="edit-fab"
4237
- aria-label="Editar stepper"
4238
- (click)="openEditor()"
4239
- >
4240
- <mat-icon fontIcon="edit"></mat-icon>
4241
- </button>
4242
- `, isInline: true, styles: [":host{display:block;position:relative}.praxis-stepper{width:100%;background:var(--md-sys-color-surface);border:1px solid var(--md-sys-color-outline-variant);border-radius:16px;padding:12px;box-shadow:var(--mat-elevation-level1)}.praxis-stepper.pdx-stepper-ft-light{background:transparent;border:none;border-radius:0;padding:0;box-shadow:none}:host(.density-compact) ::ng-deep .mat-step-header{min-height:36px}:host(.density-compact) .pdx-step-actions{padding-top:4px;gap:6px}:host(.density-comfortable) ::ng-deep .mat-step-header{min-height:44px}.pdx-step-content{padding:12px 4px 8px;color:var(--md-sys-color-on-surface)}.pdx-step-actions{display:flex;gap:8px;padding-top:8px}::ng-deep .praxis-stepper .mat-step-header{border-radius:999px;margin:4px 0;color:var(--md-sys-color-on-surface)}::ng-deep .praxis-stepper .mat-step-label{color:var(--md-sys-color-on-surface)}::ng-deep .praxis-stepper .mat-step-label.mat-step-label-selected{color:var(--md-sys-color-on-surface);font-weight:600}::ng-deep .praxis-stepper .mat-step-header.cdk-keyboard-focused,::ng-deep .praxis-stepper .mat-step-header.cdk-program-focused{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}::ng-deep .praxis-stepper .mat-step-icon{background:var(--md-sys-color-surface-container-high);color:var(--md-sys-color-on-surface)}::ng-deep .praxis-stepper .mat-step-icon-selected{background:var(--md-sys-color-primary);color:var(--md-sys-color-on-primary)}::ng-deep .praxis-stepper .mat-step-icon-state-done{background:var(--md-sys-color-tertiary);color:var(--md-sys-color-on-tertiary)}::ng-deep .praxis-stepper .mat-step-icon-state-error{background:var(--md-sys-color-error);color:var(--md-sys-color-on-error)}::ng-deep .praxis-stepper .mat-stepper-horizontal-line{border-top-color:var(--md-sys-color-outline-variant)}::ng-deep .praxis-stepper .mat-stepper-vertical-line:before{border-left-color:var(--md-sys-color-outline-variant)}::ng-deep .pdx-stepper-ft-light .mat-stepper-horizontal{background:transparent;--mat-stepper-header-hover-state-layer-color: color-mix( in srgb, var(--md-sys-color-on-surface) 8%, transparent );--mat-stepper-header-focus-state-layer-color: transparent;--mat-stepper-header-hover-state-layer-shape: 14px;--mat-stepper-header-focus-state-layer-shape: 14px}::ng-deep .pdx-stepper-ft-light .mat-step-header{margin:0}::ng-deep .pdx-stepper-ft-light .mat-step-header .mat-step-header-ripple{display:none}::ng-deep .ft-stepper{background:transparent}.ft-stepper-content{padding:0}.ft-stepper-content .form-section{border:none;padding:0;background:transparent}.nav-align-start{justify-content:flex-start}.nav-align-center{justify-content:center}.nav-align-end{justify-content:flex-end}.nav-align-space-between{justify-content:space-between}.edit-fab{position:absolute;right:12px;bottom:12px;z-index:2}.stepper-ai-assistant{position:absolute;right:12px;bottom:72px;z-index:3}.stepper-ai-assistant-trigger{box-shadow:var(--md-sys-elevation-level2, 0 4px 12px rgba(0, 0, 0, .18))}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1$1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1$1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i1$1.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: MatStepperModule }, { kind: "component", type: i2$1.MatStep, selector: "mat-step", inputs: ["color"], exportAs: ["matStep"] }, { kind: "directive", type: i2$1.MatStepLabel, selector: "[matStepLabel]" }, { kind: "component", type: i2$1.MatStepper, selector: "mat-stepper, mat-vertical-stepper, mat-horizontal-stepper, [matStepper]", inputs: ["disableRipple", "color", "labelPosition", "headerPosition", "animationDuration"], outputs: ["animationDone"], exportAs: ["matStepper", "matVerticalStepper", "matHorizontalStepper"] }, { kind: "directive", type: i2$1.MatStepperIcon, selector: "ng-template[matStepperIcon]", inputs: ["matStepperIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3$1.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$1.MatMiniFabButton, selector: "button[mat-mini-fab], a[mat-mini-fab], button[matMiniFab], a[matMiniFab]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i3$1.MatFabButton, selector: "button[mat-fab], a[mat-fab], button[matFab], a[matFab]", inputs: ["extended"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "component", type: PraxisDynamicForm, selector: "praxis-dynamic-form", inputs: ["resourcePath", "resourceId", "initialValue", "editorialContext", "mode", "config", "actions", "schemaSource", "schemaUrl", "submitUrl", "submitMethod", "responseSchemaUrl", "apiEndpointKey", "apiUrlEntry", "enableCustomization", "formId", "componentInstanceId", "configPersistenceStrategy", "layout", "backConfig", "hooks", "removeEmptyContainersOnSave", "reactiveValidation", "reactiveValidationDebounceMs", "notifyIfOutdated", "snoozeMs", "autoOpenSettingsOnOutdated", "readonlyModeGlobal", "disabledModeGlobal", "presentationModeGlobal", "visibleGlobal", "domainRules", "customEndpoints"], outputs: ["formSubmit", "formCancel", "formReset", "configChange", "configPatchChange", "formReady", "valueChange", "syncCompleted", "initializationError", "loadingStateChange", "enableCustomizationChange", "customAction", "actionConfirmation", "schemaStatusChange", "fieldRenderError", "ruleDiagnosticsChange"] }, { kind: "directive", type: DynamicWidgetLoaderDirective, selector: "[dynamicWidgetLoader]", inputs: ["dynamicWidgetLoader", "ownerWidgetKey", "context", "strictValidation", "autoWireOutputs"], outputs: ["widgetEvent", "widgetDiagnostic"], exportAs: ["dynamicWidgetLoader"] }, { kind: "component", type: EmptyStateCardComponent, selector: "praxis-empty-state-card", inputs: ["icon", "title", "description", "primaryAction", "secondaryActions", "inline", "tone"] }, { kind: "component", type: PraxisAiAssistantShellComponent, selector: "praxis-ai-assistant-shell", inputs: ["labels", "mode", "state", "contextItems", "attachments", "messages", "quickReplies", "prompt", "statusText", "errorText", "testIdPrefix", "panelTestId", "submitTestId", "applyTestId", "primaryAction", "secondaryActions", "governanceActions", "busy", "canSubmit", "canApply", "submitOnEnter", "showAttachAction", "enablePastedAttachments", "enableFileAttachments", "attachmentAccept", "attachmentMultiple", "draggable", "resizable", "minWidth", "minHeight", "margin", "layout"], outputs: ["promptChange", "submitPrompt", "apply", "retryTurn", "cancelTurn", "shellAction", "close", "attach", "attachmentsPasted", "attachmentsSelected", "removeAttachment", "messageAction", "editMessage", "resendMessage", "quickReply", "layoutChange"] }, { kind: "component", type: PraxisRichContent, selector: "praxis-rich-content", inputs: ["document", "nodes", "context", "hostCapabilities", "layout", "rootClassName"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4358
+ }
4359
+ @if (enableCustomization) {
4360
+ <button
4361
+ mat-fab
4362
+ class="edit-fab"
4363
+ aria-label="Editar stepper"
4364
+ (click)="openEditor()"
4365
+ >
4366
+ <mat-icon fontIcon="edit"></mat-icon>
4367
+ </button>
4368
+ }
4369
+ `, isInline: true, styles: [":host{display:block;position:relative}.praxis-stepper{width:100%;background:var(--md-sys-color-surface);border:1px solid var(--md-sys-color-outline-variant);border-radius:16px;padding:12px;box-shadow:var(--mat-elevation-level1)}.praxis-stepper.pdx-stepper-ft-light{background:transparent;border:none;border-radius:0;padding:0;box-shadow:none}:host(.density-compact) ::ng-deep .mat-step-header{min-height:36px}:host(.density-compact) .pdx-step-actions{padding-top:4px;gap:6px}:host(.density-comfortable) ::ng-deep .mat-step-header{min-height:44px}.pdx-step-content{padding:12px 4px 8px;color:var(--md-sys-color-on-surface)}.pdx-step-actions{display:flex;gap:8px;padding-top:8px}::ng-deep .praxis-stepper .mat-step-header{border-radius:999px;margin:4px 0;color:var(--md-sys-color-on-surface)}::ng-deep .praxis-stepper .mat-step-label{color:var(--md-sys-color-on-surface)}::ng-deep .praxis-stepper .mat-step-label.mat-step-label-selected{color:var(--md-sys-color-on-surface);font-weight:600}::ng-deep .praxis-stepper .mat-step-header.cdk-keyboard-focused,::ng-deep .praxis-stepper .mat-step-header.cdk-program-focused{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}::ng-deep .praxis-stepper .mat-step-icon{background:var(--md-sys-color-surface-container-high);color:var(--md-sys-color-on-surface)}::ng-deep .praxis-stepper .mat-step-icon-selected{background:var(--md-sys-color-primary);color:var(--md-sys-color-on-primary)}::ng-deep .praxis-stepper .mat-step-icon-state-done{background:var(--md-sys-color-tertiary);color:var(--md-sys-color-on-tertiary)}::ng-deep .praxis-stepper .mat-step-icon-state-error{background:var(--md-sys-color-error);color:var(--md-sys-color-on-error)}::ng-deep .praxis-stepper .mat-stepper-horizontal-line{border-top-color:var(--md-sys-color-outline-variant)}::ng-deep .praxis-stepper .mat-stepper-vertical-line:before{border-left-color:var(--md-sys-color-outline-variant)}::ng-deep .pdx-stepper-ft-light .mat-stepper-horizontal{background:transparent;--mat-stepper-header-hover-state-layer-color: color-mix( in srgb, var(--md-sys-color-on-surface) 8%, transparent );--mat-stepper-header-focus-state-layer-color: transparent;--mat-stepper-header-hover-state-layer-shape: 14px;--mat-stepper-header-focus-state-layer-shape: 14px}::ng-deep .pdx-stepper-ft-light .mat-step-header{margin:0}::ng-deep .pdx-stepper-ft-light .mat-step-header .mat-step-header-ripple{display:none}::ng-deep .ft-stepper{background:transparent}.ft-stepper-content{padding:0}.ft-stepper-content .form-section{border:none;padding:0;background:transparent}.nav-align-start{justify-content:flex-start}.nav-align-center{justify-content:center}.nav-align-end{justify-content:flex-end}.nav-align-space-between{justify-content:space-between}.edit-fab{position:absolute;right:12px;bottom:12px;z-index:2}.stepper-ai-assistant{position:absolute;right:12px;bottom:72px;z-index:3}.stepper-ai-assistant-trigger{box-shadow:var(--md-sys-elevation-level2, 0 4px 12px rgba(0, 0, 0, .18))}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: MatStepperModule }, { kind: "component", type: i2.MatStep, selector: "mat-step", inputs: ["color"], exportAs: ["matStep"] }, { kind: "directive", type: i2.MatStepLabel, selector: "[matStepLabel]" }, { kind: "component", type: i2.MatStepper, selector: "mat-stepper, mat-vertical-stepper, mat-horizontal-stepper, [matStepper]", inputs: ["disableRipple", "color", "labelPosition", "headerPosition", "aria-label", "headerPrefix", "animationDuration"], outputs: ["animationDone"], exportAs: ["matStepper", "matVerticalStepper", "matHorizontalStepper"] }, { kind: "directive", type: i2.MatStepperIcon, selector: "ng-template[matStepperIcon]", inputs: ["matStepperIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3$1.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$1.MatMiniFabButton, selector: "button[mat-mini-fab], a[mat-mini-fab], button[matMiniFab], a[matMiniFab]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i3$1.MatFabButton, selector: "button[mat-fab], a[mat-fab], button[matFab], a[matFab]", inputs: ["extended"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "component", type: PraxisDynamicForm, selector: "praxis-dynamic-form", inputs: ["resourcePath", "resourceId", "initialValue", "editorialContext", "mode", "config", "actions", "schemaSource", "schemaUrl", "submitUrl", "submitMethod", "responseSchemaUrl", "apiEndpointKey", "apiUrlEntry", "enableCustomization", "formId", "componentInstanceId", "configPersistenceStrategy", "layout", "backConfig", "hooks", "removeEmptyContainersOnSave", "reactiveValidation", "reactiveValidationDebounceMs", "notifyIfOutdated", "snoozeMs", "autoOpenSettingsOnOutdated", "readonlyModeGlobal", "disabledModeGlobal", "presentationModeGlobal", "visibleGlobal", "domainRules", "customEndpoints"], outputs: ["formSubmit", "formCancel", "formReset", "configChange", "configPatchChange", "formReady", "valueChange", "syncCompleted", "initializationError", "loadingStateChange", "enableCustomizationChange", "customAction", "actionConfirmation", "schemaStatusChange", "fieldRenderError", "ruleDiagnosticsChange"] }, { kind: "directive", type: DynamicWidgetLoaderDirective, selector: "[dynamicWidgetLoader]", inputs: ["dynamicWidgetLoader", "ownerWidgetKey", "context", "strictValidation", "autoWireOutputs"], outputs: ["widgetEvent", "widgetDiagnostic"], exportAs: ["dynamicWidgetLoader"] }, { kind: "component", type: EmptyStateCardComponent, selector: "praxis-empty-state-card", inputs: ["icon", "title", "description", "primaryAction", "secondaryActions", "inline", "tone"] }, { kind: "component", type: PraxisAiAssistantShellComponent, selector: "praxis-ai-assistant-shell", inputs: ["labels", "mode", "state", "contextItems", "attachments", "messages", "quickReplies", "prompt", "statusText", "errorText", "testIdPrefix", "panelTestId", "submitTestId", "applyTestId", "primaryAction", "secondaryActions", "governanceActions", "busy", "canSubmit", "canApply", "submitOnEnter", "showAttachAction", "enablePastedAttachments", "enableFileAttachments", "attachmentAccept", "attachmentMultiple", "draggable", "resizable", "minWidth", "minHeight", "margin", "layout"], outputs: ["promptChange", "submitPrompt", "apply", "retryTurn", "cancelTurn", "shellAction", "close", "attach", "attachmentsPasted", "attachmentsSelected", "removeAttachment", "messageAction", "editMessage", "resendMessage", "quickReply", "layoutChange"] }, { kind: "component", type: PraxisRichContent, selector: "praxis-rich-content", inputs: ["document", "nodes", "context", "hostCapabilities", "layout", "rootClassName"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4243
4370
  }
4244
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisStepper, decorators: [{
4371
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisStepper, decorators: [{
4245
4372
  type: Component,
4246
4373
  args: [{ selector: 'praxis-stepper', standalone: true, imports: [CommonModule, ReactiveFormsModule, MatStepperModule, MatButtonModule, MatIconModule, PraxisIconDirective, PraxisDynamicForm, DynamicWidgetLoaderDirective, EmptyStateCardComponent, PraxisAiAssistantShellComponent, PraxisRichContent], host: {
4247
4374
  '[class]': 'densityClass()'
4248
4375
  }, template: `
4249
- <div class="stepper-ai-assistant" *ngIf="enableCustomization">
4250
- <button
4251
- mat-mini-fab
4252
- color="primary"
4253
- type="button"
4254
- class="stepper-ai-assistant-trigger"
4255
- aria-label="Abrir copiloto semantico Praxis do stepper"
4256
- data-testid="praxis-stepper-ai-assistant-trigger"
4257
- (click)="openAiAssistant()"
4258
- >
4259
- <mat-icon [praxisIcon]="'auto_awesome'"></mat-icon>
4260
- </button>
4261
- </div>
4262
- <praxis-ai-assistant-shell
4263
- *ngIf="aiAssistantOpen && aiAssistantViewState"
4264
- [mode]="aiAssistantViewState.mode"
4265
- [state]="aiAssistantViewState.state"
4266
- [contextItems]="aiAssistantViewState.contextItems"
4267
- [attachments]="aiAssistantViewState.attachments"
4268
- [messages]="aiAssistantViewState.messages"
4269
- [quickReplies]="aiAssistantViewState.quickReplies"
4270
- [prompt]="aiAssistantPrompt"
4271
- [statusText]="aiAssistantViewState.statusText"
4272
- [errorText]="aiAssistantViewState.errorText"
4273
- [busy]="aiAssistantViewState.state === 'processing' || aiAssistantViewState.state === 'applying'"
4274
- [canApply]="aiAssistantViewState.canApply"
4275
- [labels]="aiAssistantLabels"
4276
- [layout]="aiAssistantLayout"
4277
- testIdPrefix="praxis-stepper-ai-assistant"
4278
- (promptChange)="onAiAssistantPromptChange($event)"
4279
- (submitPrompt)="onAiAssistantSubmit($event)"
4280
- (apply)="onAiAssistantApply()"
4281
- (retryTurn)="onAiAssistantRetry()"
4282
- (cancelTurn)="onAiAssistantCancel()"
4283
- (quickReply)="onAiAssistantQuickReply($event)"
4284
- (editMessage)="onAiAssistantEditMessage($event)"
4285
- (resendMessage)="onAiAssistantResendMessage($event)"
4286
- (layoutChange)="onAiAssistantLayoutChange($event)"
4287
- (close)="closeAiAssistant()"
4288
- ></praxis-ai-assistant-shell>
4289
- <ng-container *ngIf="steps().length > 0; else emptyState">
4290
- <mat-stepper
4291
- #stepperRoot
4292
- [linear]="linear()"
4293
- [orientation]="orientation()"
4294
- [headerPosition]="headerPosition()"
4295
- [labelPosition]="labelPos()"
4296
- [disableRipple]="disableRipple()"
4297
- [color]="stepperColor()"
4298
- [animationDuration]="animationDuration()"
4299
- [selectedIndex]="selectedIndexComputed()"
4300
- (selectionChange)="onSelectionChange($event)"
4301
- (animationDone)="onAnimationDone()"
4302
- [class]="stepperClassList()"
4303
- >
4304
- <!-- Projeção de ícones customizados do header: <ng-template matStepperIcon="done"> ... </ng-template> -->
4305
- <ng-content></ng-content>
4306
- <!-- Overrides de ícones via configuração (appearance.icons) -->
4307
- <ng-template *ngIf="icons()?.number as icn" matStepperIcon="number">
4308
- <mat-icon [praxisIcon]="icn"></mat-icon>
4309
- </ng-template>
4310
- <ng-template *ngIf="icons()?.done as icn" matStepperIcon="done">
4311
- <mat-icon [praxisIcon]="icn"></mat-icon>
4312
- </ng-template>
4313
- <ng-template *ngIf="icons()?.edit as icn" matStepperIcon="edit">
4314
- <mat-icon [praxisIcon]="icn"></mat-icon>
4315
- </ng-template>
4316
- <ng-template *ngIf="icons()?.error as icn" matStepperIcon="error">
4317
- <mat-icon [praxisIcon]="icn"></mat-icon>
4318
- </ng-template>
4319
- <mat-step *ngFor="let step of steps(); let i = index; trackBy: trackStep"
4320
- [stepControl]="$any(formGroupFor(i))"
4321
- [id]="step.id || ''"
4322
- [aria-label]="step.ariaLabel || ''"
4323
- [aria-labelledby]="step.ariaLabelledby || ''"
4324
- [label]="step.label"
4325
- [optional]="step.optional || false"
4326
- [editable]="step.editable ?? true"
4327
- [completed]="computedCompleted(i, step)"
4328
- [hasError]="computedHasError(i, step)"
4329
- [errorMessage]="step.errorMessage || ''"
4330
- [state]="step.state || step.stateIcon || ''"
4376
+ @if (enableCustomization) {
4377
+ <div class="stepper-ai-assistant">
4378
+ <button
4379
+ mat-mini-fab
4380
+ color="primary"
4381
+ type="button"
4382
+ class="stepper-ai-assistant-trigger"
4383
+ aria-label="Abrir copiloto semantico Praxis do stepper"
4384
+ data-testid="praxis-stepper-ai-assistant-trigger"
4385
+ (click)="openAiAssistant()"
4386
+ >
4387
+ <mat-icon [praxisIcon]="'auto_awesome'"></mat-icon>
4388
+ </button>
4389
+ </div>
4390
+ }
4391
+ @if (aiAssistantOpen && aiAssistantViewState) {
4392
+ <praxis-ai-assistant-shell
4393
+ [mode]="aiAssistantViewState.mode"
4394
+ [state]="aiAssistantViewState.state"
4395
+ [contextItems]="aiAssistantViewState.contextItems"
4396
+ [attachments]="aiAssistantViewState.attachments"
4397
+ [messages]="aiAssistantViewState.messages"
4398
+ [quickReplies]="aiAssistantViewState.quickReplies"
4399
+ [prompt]="aiAssistantPrompt"
4400
+ [statusText]="aiAssistantViewState.statusText"
4401
+ [errorText]="aiAssistantViewState.errorText"
4402
+ [busy]="aiAssistantViewState.state === 'processing' || aiAssistantViewState.state === 'applying'"
4403
+ [canApply]="aiAssistantViewState.canApply"
4404
+ [labels]="aiAssistantLabels"
4405
+ [layout]="aiAssistantLayout"
4406
+ testIdPrefix="praxis-stepper-ai-assistant"
4407
+ (promptChange)="onAiAssistantPromptChange($event)"
4408
+ (submitPrompt)="onAiAssistantSubmit($event)"
4409
+ (apply)="onAiAssistantApply()"
4410
+ (retryTurn)="onAiAssistantRetry()"
4411
+ (cancelTurn)="onAiAssistantCancel()"
4412
+ (quickReply)="onAiAssistantQuickReply($event)"
4413
+ (editMessage)="onAiAssistantEditMessage($event)"
4414
+ (resendMessage)="onAiAssistantResendMessage($event)"
4415
+ (layoutChange)="onAiAssistantLayoutChange($event)"
4416
+ (close)="closeAiAssistant()"
4417
+ ></praxis-ai-assistant-shell>
4418
+ }
4419
+ @if (steps().length > 0) {
4420
+ <mat-stepper
4421
+ #stepperRoot
4422
+ [linear]="linear()"
4423
+ [orientation]="orientation()"
4424
+ [headerPosition]="headerPosition()"
4425
+ [labelPosition]="labelPos()"
4426
+ [disableRipple]="disableRipple()"
4427
+ [color]="stepperColor()"
4428
+ [animationDuration]="animationDuration()"
4429
+ [selectedIndex]="selectedIndexComputed()"
4430
+ (selectionChange)="onSelectionChange($event)"
4431
+ (animationDone)="onAnimationDone()"
4432
+ [class]="stepperClassList()"
4331
4433
  >
4332
- <ng-template matStepLabel>
4333
- <ng-container *ngIf="stepLabelTpl; else plainLabel"
4334
- [ngTemplateOutlet]="stepLabelTpl"
4335
- [ngTemplateOutletContext]="{ $implicit: step, index: i }"
4336
- ></ng-container>
4337
- <ng-template #plainLabel>{{ step.label }}</ng-template>
4338
- </ng-template>
4339
- <div [class]="contentClassList()">
4340
- <praxis-rich-content
4341
- *ngIf="hasRichContent(step.stepBlocksBeforeForm)"
4342
- [document]="step.stepBlocksBeforeForm || emptyStepRichContentDocument"
4343
- [context]="getStepRichContentContext(i)"
4344
- rootClassName="pdx-step-rich-content pdx-step-rich-content--before"
4345
- ></praxis-rich-content>
4346
- <praxis-dynamic-form *ngIf="step.form as f"
4347
- [resourcePath]="f.resourcePath"
4348
- [resourceId]="$any(f.resourceId)"
4349
- [mode]="f.mode || 'create'"
4350
- [config]="f.config || { sections: [] }"
4351
- [schemaSource]="f.schemaSource || 'resource'"
4352
- [formId]="f.formId"
4353
- (formReady)="onFormReady(i, $event)"
4354
- (valueChange)="onFormValueChange(i, $event)"
4355
- ></praxis-dynamic-form>
4356
- <praxis-rich-content
4357
- *ngIf="hasRichContent(step.stepBlocksAfterForm)"
4358
- [document]="step.stepBlocksAfterForm || emptyStepRichContentDocument"
4359
- [context]="getStepRichContentContext(i)"
4360
- rootClassName="pdx-step-rich-content pdx-step-rich-content--after"
4361
- ></praxis-rich-content>
4362
- <ng-container *ngFor="let wd of step.widgets || []"
4363
- [dynamicWidgetLoader]="wd"
4364
- [context]="stepperContext"
4365
- [strictValidation]="true"
4366
- [autoWireOutputs]="true"
4367
- (widgetEvent)="onChildWidgetEvent(i, wd, $event)"></ng-container>
4368
- <ng-container *ngIf="isStepEmpty(step)">
4369
- <praxis-empty-state-card
4370
- [inline]="true"
4371
- icon="dashboard_customize"
4372
- title="Sem conteúdo nesta etapa"
4373
- description="Adicione um formulário ou widgets a esta etapa, ou abra o editor para configurar."
4374
- [primaryAction]="{ label: 'Abrir editor', icon: 'tune', action: openEditor.bind(this) }"
4375
- ></praxis-empty-state-card>
4376
- </ng-container>
4377
- </div>
4378
- <div *ngIf="navVisible()" [class]="navActionsClass()">
4379
- <!-- PREV button (hidden on first step) -->
4380
- <ng-container *ngIf="selectedIndexComputed() > 0">
4381
- <ng-container [ngSwitch]="navVariant()">
4382
- <button *ngSwitchCase="'flat'" mat-flat-button [color]="navColor()" type="button" (click)="onPrev()">
4383
- <mat-icon *ngIf="navPrevIcon() as ic" [praxisIcon]="ic"></mat-icon>
4384
- {{ navPrevLabel() }}
4385
- </button>
4386
- <button *ngSwitchCase="'stroked'" mat-stroked-button [color]="navColor()" type="button" (click)="onPrev()">
4387
- <mat-icon *ngIf="navPrevIcon() as ic" [praxisIcon]="ic"></mat-icon>
4388
- {{ navPrevLabel() }}
4389
- </button>
4390
- <button *ngSwitchCase="'raised'" mat-raised-button [color]="navColor()" type="button" (click)="onPrev()">
4391
- <mat-icon *ngIf="navPrevIcon() as ic" [praxisIcon]="ic"></mat-icon>
4392
- {{ navPrevLabel() }}
4393
- </button>
4394
- <button *ngSwitchDefault mat-button [color]="navColor()" type="button" (click)="onPrev()">
4395
- <mat-icon *ngIf="navPrevIcon() as ic" [praxisIcon]="ic"></mat-icon>
4396
- {{ navPrevLabel() }}
4397
- </button>
4398
- </ng-container>
4399
- </ng-container>
4400
-
4401
- <!-- NEXT button -->
4402
- <ng-container [ngSwitch]="navVariant()">
4403
- <button *ngSwitchCase="'flat'" mat-flat-button [color]="navColor()" type="button" (click)="onNext(i)" [disabled]="isNextDisabled(i)">
4404
- {{ navNextLabel() }}
4405
- <mat-icon *ngIf="navNextIcon() as ic" [praxisIcon]="ic"></mat-icon>
4406
- </button>
4407
- <button *ngSwitchCase="'stroked'" mat-stroked-button [color]="navColor()" type="button" (click)="onNext(i)" [disabled]="isNextDisabled(i)">
4408
- {{ navNextLabel() }}
4409
- <mat-icon *ngIf="navNextIcon() as ic" [praxisIcon]="ic"></mat-icon>
4410
- </button>
4411
- <button *ngSwitchCase="'raised'" mat-raised-button [color]="navColor()" type="button" (click)="onNext(i)" [disabled]="isNextDisabled(i)">
4412
- {{ navNextLabel() }}
4413
- <mat-icon *ngIf="navNextIcon() as ic" [praxisIcon]="ic"></mat-icon>
4414
- </button>
4415
- <button *ngSwitchDefault mat-button [color]="navColor()" type="button" (click)="onNext(i)" [disabled]="isNextDisabled(i)">
4416
- {{ navNextLabel() }}
4417
- <mat-icon *ngIf="navNextIcon() as ic" [praxisIcon]="ic"></mat-icon>
4418
- </button>
4419
- </ng-container>
4420
- </div>
4421
- </mat-step>
4422
- </mat-stepper>
4423
- </ng-container>
4424
- <ng-template #emptyState>
4434
+ <!-- Projeção de ícones customizados do header: <ng-template matStepperIcon="done"> ... </ng-template> -->
4435
+ <ng-content></ng-content>
4436
+ <!-- Overrides de ícones via configuração (appearance.icons) -->
4437
+ @if (icons()?.number; as icn) {
4438
+ <ng-template matStepperIcon="number">
4439
+ <mat-icon [praxisIcon]="icn"></mat-icon>
4440
+ </ng-template>
4441
+ }
4442
+ @if (icons()?.done; as icn) {
4443
+ <ng-template matStepperIcon="done">
4444
+ <mat-icon [praxisIcon]="icn"></mat-icon>
4445
+ </ng-template>
4446
+ }
4447
+ @if (icons()?.edit; as icn) {
4448
+ <ng-template matStepperIcon="edit">
4449
+ <mat-icon [praxisIcon]="icn"></mat-icon>
4450
+ </ng-template>
4451
+ }
4452
+ @if (icons()?.error; as icn) {
4453
+ <ng-template matStepperIcon="error">
4454
+ <mat-icon [praxisIcon]="icn"></mat-icon>
4455
+ </ng-template>
4456
+ }
4457
+ @for (step of steps(); track trackStep(i, step); let i = $index) {
4458
+ <mat-step
4459
+ [stepControl]="$any(formGroupFor(i))"
4460
+ [id]="step.id || ''"
4461
+ [aria-label]="step.ariaLabel || ''"
4462
+ [aria-labelledby]="step.ariaLabelledby || ''"
4463
+ [label]="step.label"
4464
+ [optional]="step.optional || false"
4465
+ [editable]="step.editable ?? true"
4466
+ [completed]="computedCompleted(i, step)"
4467
+ [hasError]="computedHasError(i, step)"
4468
+ [errorMessage]="step.errorMessage || ''"
4469
+ [state]="step.state || step.stateIcon || ''"
4470
+ >
4471
+ <ng-template matStepLabel>
4472
+ @if (stepLabelTpl) {
4473
+ <ng-container
4474
+ [ngTemplateOutlet]="stepLabelTpl"
4475
+ [ngTemplateOutletContext]="{ $implicit: step, index: i }"
4476
+ ></ng-container>
4477
+ } @else {
4478
+ {{ step.label }}
4479
+ }
4480
+ </ng-template>
4481
+ <div [class]="contentClassList()">
4482
+ @if (hasRichContent(step.stepBlocksBeforeForm)) {
4483
+ <praxis-rich-content
4484
+ [document]="step.stepBlocksBeforeForm || emptyStepRichContentDocument"
4485
+ [context]="getStepRichContentContext(i)"
4486
+ rootClassName="pdx-step-rich-content pdx-step-rich-content--before"
4487
+ ></praxis-rich-content>
4488
+ }
4489
+ @if (step.form; as f) {
4490
+ <praxis-dynamic-form
4491
+ [resourcePath]="f.resourcePath"
4492
+ [resourceId]="$any(f.resourceId)"
4493
+ [mode]="f.mode || 'create'"
4494
+ [config]="f.config || { sections: [] }"
4495
+ [schemaSource]="f.schemaSource || 'resource'"
4496
+ [formId]="f.formId"
4497
+ (formReady)="onFormReady(i, $event)"
4498
+ (valueChange)="onFormValueChange(i, $event)"
4499
+ ></praxis-dynamic-form>
4500
+ }
4501
+ @if (hasRichContent(step.stepBlocksAfterForm)) {
4502
+ <praxis-rich-content
4503
+ [document]="step.stepBlocksAfterForm || emptyStepRichContentDocument"
4504
+ [context]="getStepRichContentContext(i)"
4505
+ rootClassName="pdx-step-rich-content pdx-step-rich-content--after"
4506
+ ></praxis-rich-content>
4507
+ }
4508
+ @for (wd of step.widgets || []; track wd) {
4509
+ <ng-container
4510
+ [dynamicWidgetLoader]="wd"
4511
+ [context]="stepperContext"
4512
+ [strictValidation]="true"
4513
+ [autoWireOutputs]="true"
4514
+ (widgetEvent)="onChildWidgetEvent(i, wd, $event)"></ng-container>
4515
+ }
4516
+ @if (isStepEmpty(step)) {
4517
+ <praxis-empty-state-card
4518
+ [inline]="true"
4519
+ icon="dashboard_customize"
4520
+ title="Sem conteúdo nesta etapa"
4521
+ description="Adicione um formulário ou widgets a esta etapa, ou abra o editor para configurar."
4522
+ [primaryAction]="{ label: 'Abrir editor', icon: 'tune', action: openEditor.bind(this) }"
4523
+ ></praxis-empty-state-card>
4524
+ }
4525
+ </div>
4526
+ @if (navVisible()) {
4527
+ <div [class]="navActionsClass()">
4528
+ <!-- PREV button (hidden on first step) -->
4529
+ @if (selectedIndexComputed() > 0) {
4530
+ @switch (navVariant()) {
4531
+ @case ('flat') {
4532
+ <button mat-flat-button [color]="navColor()" type="button" (click)="onPrev()">
4533
+ @if (navPrevIcon(); as ic) {
4534
+ <mat-icon [praxisIcon]="ic"></mat-icon>
4535
+ }
4536
+ {{ navPrevLabel() }}
4537
+ </button>
4538
+ }
4539
+ @case ('stroked') {
4540
+ <button mat-stroked-button [color]="navColor()" type="button" (click)="onPrev()">
4541
+ @if (navPrevIcon(); as ic) {
4542
+ <mat-icon [praxisIcon]="ic"></mat-icon>
4543
+ }
4544
+ {{ navPrevLabel() }}
4545
+ </button>
4546
+ }
4547
+ @case ('raised') {
4548
+ <button mat-raised-button [color]="navColor()" type="button" (click)="onPrev()">
4549
+ @if (navPrevIcon(); as ic) {
4550
+ <mat-icon [praxisIcon]="ic"></mat-icon>
4551
+ }
4552
+ {{ navPrevLabel() }}
4553
+ </button>
4554
+ }
4555
+ @default {
4556
+ <button mat-button [color]="navColor()" type="button" (click)="onPrev()">
4557
+ @if (navPrevIcon(); as ic) {
4558
+ <mat-icon [praxisIcon]="ic"></mat-icon>
4559
+ }
4560
+ {{ navPrevLabel() }}
4561
+ </button>
4562
+ }
4563
+ }
4564
+ }
4565
+ <!-- NEXT button -->
4566
+ @switch (navVariant()) {
4567
+ @case ('flat') {
4568
+ <button mat-flat-button [color]="navColor()" type="button" (click)="onNext(i)" [disabled]="isNextDisabled(i)">
4569
+ {{ navNextLabel() }}
4570
+ @if (navNextIcon(); as ic) {
4571
+ <mat-icon [praxisIcon]="ic"></mat-icon>
4572
+ }
4573
+ </button>
4574
+ }
4575
+ @case ('stroked') {
4576
+ <button mat-stroked-button [color]="navColor()" type="button" (click)="onNext(i)" [disabled]="isNextDisabled(i)">
4577
+ {{ navNextLabel() }}
4578
+ @if (navNextIcon(); as ic) {
4579
+ <mat-icon [praxisIcon]="ic"></mat-icon>
4580
+ }
4581
+ </button>
4582
+ }
4583
+ @case ('raised') {
4584
+ <button mat-raised-button [color]="navColor()" type="button" (click)="onNext(i)" [disabled]="isNextDisabled(i)">
4585
+ {{ navNextLabel() }}
4586
+ @if (navNextIcon(); as ic) {
4587
+ <mat-icon [praxisIcon]="ic"></mat-icon>
4588
+ }
4589
+ </button>
4590
+ }
4591
+ @default {
4592
+ <button mat-button [color]="navColor()" type="button" (click)="onNext(i)" [disabled]="isNextDisabled(i)">
4593
+ {{ navNextLabel() }}
4594
+ @if (navNextIcon(); as ic) {
4595
+ <mat-icon [praxisIcon]="ic"></mat-icon>
4596
+ }
4597
+ </button>
4598
+ }
4599
+ }
4600
+ </div>
4601
+ }
4602
+ </mat-step>
4603
+ }
4604
+ </mat-stepper>
4605
+ } @else {
4425
4606
  <praxis-empty-state-card
4426
4607
  icon="view_timeline"
4427
4608
  [inline]="true"
@@ -4430,17 +4611,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
4430
4611
  [primaryAction]="primaryCta"
4431
4612
  [secondaryActions]="secondaryCtas"
4432
4613
  ></praxis-empty-state-card>
4433
- </ng-template>
4434
- <button
4435
- *ngIf="enableCustomization"
4436
- mat-fab
4437
- class="edit-fab"
4438
- aria-label="Editar stepper"
4439
- (click)="openEditor()"
4440
- >
4441
- <mat-icon fontIcon="edit"></mat-icon>
4442
- </button>
4443
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block;position:relative}.praxis-stepper{width:100%;background:var(--md-sys-color-surface);border:1px solid var(--md-sys-color-outline-variant);border-radius:16px;padding:12px;box-shadow:var(--mat-elevation-level1)}.praxis-stepper.pdx-stepper-ft-light{background:transparent;border:none;border-radius:0;padding:0;box-shadow:none}:host(.density-compact) ::ng-deep .mat-step-header{min-height:36px}:host(.density-compact) .pdx-step-actions{padding-top:4px;gap:6px}:host(.density-comfortable) ::ng-deep .mat-step-header{min-height:44px}.pdx-step-content{padding:12px 4px 8px;color:var(--md-sys-color-on-surface)}.pdx-step-actions{display:flex;gap:8px;padding-top:8px}::ng-deep .praxis-stepper .mat-step-header{border-radius:999px;margin:4px 0;color:var(--md-sys-color-on-surface)}::ng-deep .praxis-stepper .mat-step-label{color:var(--md-sys-color-on-surface)}::ng-deep .praxis-stepper .mat-step-label.mat-step-label-selected{color:var(--md-sys-color-on-surface);font-weight:600}::ng-deep .praxis-stepper .mat-step-header.cdk-keyboard-focused,::ng-deep .praxis-stepper .mat-step-header.cdk-program-focused{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}::ng-deep .praxis-stepper .mat-step-icon{background:var(--md-sys-color-surface-container-high);color:var(--md-sys-color-on-surface)}::ng-deep .praxis-stepper .mat-step-icon-selected{background:var(--md-sys-color-primary);color:var(--md-sys-color-on-primary)}::ng-deep .praxis-stepper .mat-step-icon-state-done{background:var(--md-sys-color-tertiary);color:var(--md-sys-color-on-tertiary)}::ng-deep .praxis-stepper .mat-step-icon-state-error{background:var(--md-sys-color-error);color:var(--md-sys-color-on-error)}::ng-deep .praxis-stepper .mat-stepper-horizontal-line{border-top-color:var(--md-sys-color-outline-variant)}::ng-deep .praxis-stepper .mat-stepper-vertical-line:before{border-left-color:var(--md-sys-color-outline-variant)}::ng-deep .pdx-stepper-ft-light .mat-stepper-horizontal{background:transparent;--mat-stepper-header-hover-state-layer-color: color-mix( in srgb, var(--md-sys-color-on-surface) 8%, transparent );--mat-stepper-header-focus-state-layer-color: transparent;--mat-stepper-header-hover-state-layer-shape: 14px;--mat-stepper-header-focus-state-layer-shape: 14px}::ng-deep .pdx-stepper-ft-light .mat-step-header{margin:0}::ng-deep .pdx-stepper-ft-light .mat-step-header .mat-step-header-ripple{display:none}::ng-deep .ft-stepper{background:transparent}.ft-stepper-content{padding:0}.ft-stepper-content .form-section{border:none;padding:0;background:transparent}.nav-align-start{justify-content:flex-start}.nav-align-center{justify-content:center}.nav-align-end{justify-content:flex-end}.nav-align-space-between{justify-content:space-between}.edit-fab{position:absolute;right:12px;bottom:12px;z-index:2}.stepper-ai-assistant{position:absolute;right:12px;bottom:72px;z-index:3}.stepper-ai-assistant-trigger{box-shadow:var(--md-sys-elevation-level2, 0 4px 12px rgba(0, 0, 0, .18))}\n"] }]
4614
+ }
4615
+ @if (enableCustomization) {
4616
+ <button
4617
+ mat-fab
4618
+ class="edit-fab"
4619
+ aria-label="Editar stepper"
4620
+ (click)="openEditor()"
4621
+ >
4622
+ <mat-icon fontIcon="edit"></mat-icon>
4623
+ </button>
4624
+ }
4625
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block;position:relative}.praxis-stepper{width:100%;background:var(--md-sys-color-surface);border:1px solid var(--md-sys-color-outline-variant);border-radius:16px;padding:12px;box-shadow:var(--mat-elevation-level1)}.praxis-stepper.pdx-stepper-ft-light{background:transparent;border:none;border-radius:0;padding:0;box-shadow:none}:host(.density-compact) ::ng-deep .mat-step-header{min-height:36px}:host(.density-compact) .pdx-step-actions{padding-top:4px;gap:6px}:host(.density-comfortable) ::ng-deep .mat-step-header{min-height:44px}.pdx-step-content{padding:12px 4px 8px;color:var(--md-sys-color-on-surface)}.pdx-step-actions{display:flex;gap:8px;padding-top:8px}::ng-deep .praxis-stepper .mat-step-header{border-radius:999px;margin:4px 0;color:var(--md-sys-color-on-surface)}::ng-deep .praxis-stepper .mat-step-label{color:var(--md-sys-color-on-surface)}::ng-deep .praxis-stepper .mat-step-label.mat-step-label-selected{color:var(--md-sys-color-on-surface);font-weight:600}::ng-deep .praxis-stepper .mat-step-header.cdk-keyboard-focused,::ng-deep .praxis-stepper .mat-step-header.cdk-program-focused{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}::ng-deep .praxis-stepper .mat-step-icon{background:var(--md-sys-color-surface-container-high);color:var(--md-sys-color-on-surface)}::ng-deep .praxis-stepper .mat-step-icon-selected{background:var(--md-sys-color-primary);color:var(--md-sys-color-on-primary)}::ng-deep .praxis-stepper .mat-step-icon-state-done{background:var(--md-sys-color-tertiary);color:var(--md-sys-color-on-tertiary)}::ng-deep .praxis-stepper .mat-step-icon-state-error{background:var(--md-sys-color-error);color:var(--md-sys-color-on-error)}::ng-deep .praxis-stepper .mat-stepper-horizontal-line{border-top-color:var(--md-sys-color-outline-variant)}::ng-deep .praxis-stepper .mat-stepper-vertical-line:before{border-left-color:var(--md-sys-color-outline-variant)}::ng-deep .pdx-stepper-ft-light .mat-stepper-horizontal{background:transparent;--mat-stepper-header-hover-state-layer-color: color-mix( in srgb, var(--md-sys-color-on-surface) 8%, transparent );--mat-stepper-header-focus-state-layer-color: transparent;--mat-stepper-header-hover-state-layer-shape: 14px;--mat-stepper-header-focus-state-layer-shape: 14px}::ng-deep .pdx-stepper-ft-light .mat-step-header{margin:0}::ng-deep .pdx-stepper-ft-light .mat-step-header .mat-step-header-ripple{display:none}::ng-deep .ft-stepper{background:transparent}.ft-stepper-content{padding:0}.ft-stepper-content .form-section{border:none;padding:0;background:transparent}.nav-align-start{justify-content:flex-start}.nav-align-center{justify-content:center}.nav-align-end{justify-content:flex-end}.nav-align-space-between{justify-content:space-between}.edit-fab{position:absolute;right:12px;bottom:12px;z-index:2}.stepper-ai-assistant{position:absolute;right:12px;bottom:72px;z-index:3}.stepper-ai-assistant-trigger{box-shadow:var(--md-sys-elevation-level2, 0 4px 12px rgba(0, 0, 0, .18))}\n"] }]
4444
4626
  }], propDecorators: { stepLabelTpl: [{
4445
4627
  type: ContentChild,
4446
4628
  args: ['stepLabelTpl', { read: TemplateRef }]
@@ -4532,19 +4714,19 @@ class PraxisStepperWidgetConfigEditor {
4532
4714
  },
4533
4715
  };
4534
4716
  }
4535
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisStepperWidgetConfigEditor, deps: [], target: i0.ɵɵFactoryTarget.Component });
4536
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.17", type: PraxisStepperWidgetConfigEditor, isStandalone: true, selector: "praxis-stepper-widget-config-editor", inputs: { inputs: "inputs", widgetKey: "widgetKey" }, viewQueries: [{ propertyName: "stepperEditor", first: true, predicate: ["stepperEditor"], descendants: true }], ngImport: i0, template: `
4717
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisStepperWidgetConfigEditor, deps: [], target: i0.ɵɵFactoryTarget.Component });
4718
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.14", type: PraxisStepperWidgetConfigEditor, isStandalone: true, selector: "praxis-stepper-widget-config-editor", inputs: { inputs: "inputs", widgetKey: "widgetKey" }, viewQueries: [{ propertyName: "stepperEditor", first: true, predicate: ["stepperEditor"], descendants: true }], ngImport: i0, template: `
4537
4719
  <section data-testid="stepper-widget-config-editor">
4538
4720
  <praxis-stepper-config-editor #stepperEditor [stepperConfig]="config" />
4539
4721
  </section>
4540
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: PraxisStepperConfigEditor, selector: "praxis-stepper-config-editor", inputs: ["stepperConfig"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4722
+ `, isInline: true, dependencies: [{ kind: "component", type: PraxisStepperConfigEditor, selector: "praxis-stepper-config-editor", inputs: ["stepperConfig"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4541
4723
  }
4542
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisStepperWidgetConfigEditor, decorators: [{
4724
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisStepperWidgetConfigEditor, decorators: [{
4543
4725
  type: Component,
4544
4726
  args: [{
4545
4727
  selector: 'praxis-stepper-widget-config-editor',
4546
4728
  standalone: true,
4547
- imports: [CommonModule, PraxisStepperConfigEditor],
4729
+ imports: [PraxisStepperConfigEditor],
4548
4730
  template: `
4549
4731
  <section data-testid="stepper-widget-config-editor">
4550
4732
  <praxis-stepper-config-editor #stepperEditor [stepperConfig]="config" />
@@ -4567,48 +4749,60 @@ class PraxisWizardBenefitsGridComponent {
4567
4749
  items = [];
4568
4750
  columns;
4569
4751
  boxed = true;
4570
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisWizardBenefitsGridComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4571
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.17", type: PraxisWizardBenefitsGridComponent, isStandalone: true, selector: "praxis-wizard-benefits-grid", inputs: { blockId: "blockId", title: "title", items: "items", columns: "columns", boxed: "boxed" }, host: { properties: { "attr.data-block-id": "blockId || null" } }, ngImport: i0, template: `
4752
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisWizardBenefitsGridComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4753
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PraxisWizardBenefitsGridComponent, isStandalone: true, selector: "praxis-wizard-benefits-grid", inputs: { blockId: "blockId", title: "title", items: "items", columns: "columns", boxed: "boxed" }, host: { properties: { "attr.data-block-id": "blockId || null" } }, ngImport: i0, template: `
4572
4754
  <section class="pwx-benefits">
4573
4755
  @if (title) {
4574
4756
  <h3 class="pwx-benefits-title">{{ title }}</h3>
4575
4757
  }
4576
4758
  <div class="pwx-benefits-grid" [class.is-boxed]="boxed" [style.--pwx-columns]="columns || 4">
4577
- <div class="pwx-benefit" *ngFor="let item of items">
4578
- <div class="pwx-benefit-icon" *ngIf="item.icon">
4579
- <mat-icon [fontIcon]="item.icon"></mat-icon>
4580
- </div>
4581
- <div class="pwx-benefit-body">
4582
- <div class="pwx-benefit-title">{{ item.title }}</div>
4583
- <div class="pwx-benefit-text" *ngIf="item.text">{{ item.text }}</div>
4759
+ @for (item of items; track item) {
4760
+ <div class="pwx-benefit">
4761
+ @if (item.icon) {
4762
+ <div class="pwx-benefit-icon">
4763
+ <mat-icon [fontIcon]="item.icon"></mat-icon>
4764
+ </div>
4765
+ }
4766
+ <div class="pwx-benefit-body">
4767
+ <div class="pwx-benefit-title">{{ item.title }}</div>
4768
+ @if (item.text) {
4769
+ <div class="pwx-benefit-text">{{ item.text }}</div>
4770
+ }
4771
+ </div>
4584
4772
  </div>
4585
- </div>
4773
+ }
4586
4774
  </div>
4587
4775
  </section>
4588
- `, isInline: true, styles: [":host{display:block}.pwx-benefits{display:flex;flex-direction:column;gap:10px}.pwx-benefits-title{margin:0;font-size:.9rem;font-weight:600;color:var(--md-sys-color-on-surface);letter-spacing:.02em;display:flex;align-items:center;gap:12px}.pwx-benefits-title:before,.pwx-benefits-title:after{content:\"\";height:1px;flex:1;background:var(--md-sys-color-outline-variant)}.pwx-benefits-grid{display:grid;grid-template-columns:repeat(var(--pwx-columns),minmax(0,1fr));gap:12px 16px;align-items:start}.pwx-benefits-grid.is-boxed{padding:12px 14px;border:1px solid var(--md-sys-color-outline-variant);border-radius:6px;background:var(--md-sys-color-surface)}.pwx-benefit{display:flex;gap:10px;align-items:flex-start;min-height:0}.pwx-benefit-icon{width:24px;min-width:24px;height:24px;display:inline-flex;align-items:center;justify-content:center;line-height:1;color:var(--praxis-wizard-accent, var(--md-sys-color-primary))}.pwx-benefit-icon mat-icon{width:24px;height:24px;font-size:24px;line-height:24px;display:block;overflow:visible}.pwx-benefit-title{font-weight:600;font-size:.88rem;color:var(--md-sys-color-on-surface)}.pwx-benefit-text{font-size:.82rem;color:var(--praxis-wizard-muted, var(--md-sys-color-on-surface-variant));line-height:1.35}@media(max-width:720px){.pwx-benefits-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}@media(max-width:480px){.pwx-benefits-grid{grid-template-columns:1fr}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4776
+ `, isInline: true, styles: [":host{display:block}.pwx-benefits{display:flex;flex-direction:column;gap:10px}.pwx-benefits-title{margin:0;font-size:.9rem;font-weight:600;color:var(--md-sys-color-on-surface);letter-spacing:.02em;display:flex;align-items:center;gap:12px}.pwx-benefits-title:before,.pwx-benefits-title:after{content:\"\";height:1px;flex:1;background:var(--md-sys-color-outline-variant)}.pwx-benefits-grid{display:grid;grid-template-columns:repeat(var(--pwx-columns),minmax(0,1fr));gap:12px 16px;align-items:start}.pwx-benefits-grid.is-boxed{padding:12px 14px;border:1px solid var(--md-sys-color-outline-variant);border-radius:6px;background:var(--md-sys-color-surface)}.pwx-benefit{display:flex;gap:10px;align-items:flex-start;min-height:0}.pwx-benefit-icon{width:24px;min-width:24px;height:24px;display:inline-flex;align-items:center;justify-content:center;line-height:1;color:var(--praxis-wizard-accent, var(--md-sys-color-primary))}.pwx-benefit-icon mat-icon{width:24px;height:24px;font-size:24px;line-height:24px;display:block;overflow:visible}.pwx-benefit-title{font-weight:600;font-size:.88rem;color:var(--md-sys-color-on-surface)}.pwx-benefit-text{font-size:.82rem;color:var(--praxis-wizard-muted, var(--md-sys-color-on-surface-variant));line-height:1.35}@media(max-width:720px){.pwx-benefits-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}@media(max-width:480px){.pwx-benefits-grid{grid-template-columns:1fr}}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4589
4777
  }
4590
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisWizardBenefitsGridComponent, decorators: [{
4778
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisWizardBenefitsGridComponent, decorators: [{
4591
4779
  type: Component,
4592
4780
  args: [{ selector: 'praxis-wizard-benefits-grid', standalone: true, host: {
4593
4781
  '[attr.data-block-id]': 'blockId || null',
4594
- }, imports: [CommonModule, MatIconModule], template: `
4782
+ }, imports: [MatIconModule], template: `
4595
4783
  <section class="pwx-benefits">
4596
4784
  @if (title) {
4597
4785
  <h3 class="pwx-benefits-title">{{ title }}</h3>
4598
4786
  }
4599
4787
  <div class="pwx-benefits-grid" [class.is-boxed]="boxed" [style.--pwx-columns]="columns || 4">
4600
- <div class="pwx-benefit" *ngFor="let item of items">
4601
- <div class="pwx-benefit-icon" *ngIf="item.icon">
4602
- <mat-icon [fontIcon]="item.icon"></mat-icon>
4603
- </div>
4604
- <div class="pwx-benefit-body">
4605
- <div class="pwx-benefit-title">{{ item.title }}</div>
4606
- <div class="pwx-benefit-text" *ngIf="item.text">{{ item.text }}</div>
4788
+ @for (item of items; track item) {
4789
+ <div class="pwx-benefit">
4790
+ @if (item.icon) {
4791
+ <div class="pwx-benefit-icon">
4792
+ <mat-icon [fontIcon]="item.icon"></mat-icon>
4793
+ </div>
4794
+ }
4795
+ <div class="pwx-benefit-body">
4796
+ <div class="pwx-benefit-title">{{ item.title }}</div>
4797
+ @if (item.text) {
4798
+ <div class="pwx-benefit-text">{{ item.text }}</div>
4799
+ }
4800
+ </div>
4607
4801
  </div>
4608
- </div>
4802
+ }
4609
4803
  </div>
4610
4804
  </section>
4611
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block}.pwx-benefits{display:flex;flex-direction:column;gap:10px}.pwx-benefits-title{margin:0;font-size:.9rem;font-weight:600;color:var(--md-sys-color-on-surface);letter-spacing:.02em;display:flex;align-items:center;gap:12px}.pwx-benefits-title:before,.pwx-benefits-title:after{content:\"\";height:1px;flex:1;background:var(--md-sys-color-outline-variant)}.pwx-benefits-grid{display:grid;grid-template-columns:repeat(var(--pwx-columns),minmax(0,1fr));gap:12px 16px;align-items:start}.pwx-benefits-grid.is-boxed{padding:12px 14px;border:1px solid var(--md-sys-color-outline-variant);border-radius:6px;background:var(--md-sys-color-surface)}.pwx-benefit{display:flex;gap:10px;align-items:flex-start;min-height:0}.pwx-benefit-icon{width:24px;min-width:24px;height:24px;display:inline-flex;align-items:center;justify-content:center;line-height:1;color:var(--praxis-wizard-accent, var(--md-sys-color-primary))}.pwx-benefit-icon mat-icon{width:24px;height:24px;font-size:24px;line-height:24px;display:block;overflow:visible}.pwx-benefit-title{font-weight:600;font-size:.88rem;color:var(--md-sys-color-on-surface)}.pwx-benefit-text{font-size:.82rem;color:var(--praxis-wizard-muted, var(--md-sys-color-on-surface-variant));line-height:1.35}@media(max-width:720px){.pwx-benefits-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}@media(max-width:480px){.pwx-benefits-grid{grid-template-columns:1fr}}\n"] }]
4805
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block}.pwx-benefits{display:flex;flex-direction:column;gap:10px}.pwx-benefits-title{margin:0;font-size:.9rem;font-weight:600;color:var(--md-sys-color-on-surface);letter-spacing:.02em;display:flex;align-items:center;gap:12px}.pwx-benefits-title:before,.pwx-benefits-title:after{content:\"\";height:1px;flex:1;background:var(--md-sys-color-outline-variant)}.pwx-benefits-grid{display:grid;grid-template-columns:repeat(var(--pwx-columns),minmax(0,1fr));gap:12px 16px;align-items:start}.pwx-benefits-grid.is-boxed{padding:12px 14px;border:1px solid var(--md-sys-color-outline-variant);border-radius:6px;background:var(--md-sys-color-surface)}.pwx-benefit{display:flex;gap:10px;align-items:flex-start;min-height:0}.pwx-benefit-icon{width:24px;min-width:24px;height:24px;display:inline-flex;align-items:center;justify-content:center;line-height:1;color:var(--praxis-wizard-accent, var(--md-sys-color-primary))}.pwx-benefit-icon mat-icon{width:24px;height:24px;font-size:24px;line-height:24px;display:block;overflow:visible}.pwx-benefit-title{font-weight:600;font-size:.88rem;color:var(--md-sys-color-on-surface)}.pwx-benefit-text{font-size:.82rem;color:var(--praxis-wizard-muted, var(--md-sys-color-on-surface-variant));line-height:1.35}@media(max-width:720px){.pwx-benefits-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}@media(max-width:480px){.pwx-benefits-grid{grid-template-columns:1fr}}\n"] }]
4612
4806
  }], propDecorators: { blockId: [{
4613
4807
  type: Input
4614
4808
  }], title: [{
@@ -4627,8 +4821,8 @@ class PraxisWizardContentBlockComponent {
4627
4821
  subtitle;
4628
4822
  text;
4629
4823
  caption;
4630
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisWizardContentBlockComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4631
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.17", type: PraxisWizardContentBlockComponent, isStandalone: true, selector: "praxis-wizard-content-block", inputs: { blockId: "blockId", title: "title", subtitle: "subtitle", text: "text", caption: "caption" }, host: { properties: { "attr.data-block-id": "blockId || null" } }, ngImport: i0, template: `
4824
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisWizardContentBlockComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4825
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PraxisWizardContentBlockComponent, isStandalone: true, selector: "praxis-wizard-content-block", inputs: { blockId: "blockId", title: "title", subtitle: "subtitle", text: "text", caption: "caption" }, host: { properties: { "attr.data-block-id": "blockId || null" } }, ngImport: i0, template: `
4632
4826
  <section class="pwx-content">
4633
4827
  @if (title) {
4634
4828
  <h3 class="pwx-content-title">{{ title }}</h3>
@@ -4643,13 +4837,13 @@ class PraxisWizardContentBlockComponent {
4643
4837
  <div class="pwx-content-caption">{{ caption }}</div>
4644
4838
  }
4645
4839
  </section>
4646
- `, isInline: true, styles: [":host{display:block}.pwx-content{display:flex;flex-direction:column;gap:6px}.pwx-content-title{margin:0;font-size:1.05rem;font-weight:600;color:var(--md-sys-color-on-surface)}.pwx-content-subtitle{font-size:.95rem;color:var(--md-sys-color-on-surface)}.pwx-content-text{margin:0;font-size:.88rem;color:var(--praxis-wizard-muted, var(--md-sys-color-on-surface-variant))}.pwx-content-caption{font-size:.78rem;color:var(--praxis-wizard-muted, var(--md-sys-color-on-surface-variant))}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4840
+ `, isInline: true, styles: [":host{display:block}.pwx-content{display:flex;flex-direction:column;gap:6px}.pwx-content-title{margin:0;font-size:1.05rem;font-weight:600;color:var(--md-sys-color-on-surface)}.pwx-content-subtitle{font-size:.95rem;color:var(--md-sys-color-on-surface)}.pwx-content-text{margin:0;font-size:.88rem;color:var(--praxis-wizard-muted, var(--md-sys-color-on-surface-variant))}.pwx-content-caption{font-size:.78rem;color:var(--praxis-wizard-muted, var(--md-sys-color-on-surface-variant))}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4647
4841
  }
4648
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisWizardContentBlockComponent, decorators: [{
4842
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisWizardContentBlockComponent, decorators: [{
4649
4843
  type: Component,
4650
4844
  args: [{ selector: 'praxis-wizard-content-block', standalone: true, host: {
4651
4845
  '[attr.data-block-id]': 'blockId || null',
4652
- }, imports: [CommonModule], template: `
4846
+ }, imports: [], template: `
4653
4847
  <section class="pwx-content">
4654
4848
  @if (title) {
4655
4849
  <h3 class="pwx-content-title">{{ title }}</h3>
@@ -4684,14 +4878,14 @@ class PraxisWizardInlineNoticeComponent {
4684
4878
  get toneClass() {
4685
4879
  return this.tone !== 'neutral' ? this.tone : '';
4686
4880
  }
4687
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisWizardInlineNoticeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4688
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.17", type: PraxisWizardInlineNoticeComponent, isStandalone: true, selector: "praxis-wizard-inline-notice", inputs: { blockId: "blockId", text: "text", tone: "tone" }, host: { properties: { "attr.data-block-id": "blockId || null" } }, ngImport: i0, template: `
4881
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisWizardInlineNoticeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4882
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.14", type: PraxisWizardInlineNoticeComponent, isStandalone: true, selector: "praxis-wizard-inline-notice", inputs: { blockId: "blockId", text: "text", tone: "tone" }, host: { properties: { "attr.data-block-id": "blockId || null" } }, ngImport: i0, template: `
4689
4883
  <div class="pwx-inline" [ngClass]="toneClass">
4690
4884
  {{ text }}
4691
4885
  </div>
4692
- `, isInline: true, styles: [":host{display:block}.pwx-inline{font-size:.82rem;color:var(--praxis-wizard-muted, var(--md-sys-color-on-surface-variant));line-height:1.4}.pwx-inline.info{color:var(--md-sys-color-on-surface)}.pwx-inline.warning{color:var(--md-sys-color-error)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4886
+ `, isInline: true, styles: [":host{display:block}.pwx-inline{font-size:.82rem;color:var(--praxis-wizard-muted, var(--md-sys-color-on-surface-variant));line-height:1.4}.pwx-inline.info{color:var(--md-sys-color-on-surface)}.pwx-inline.warning{color:var(--md-sys-color-error)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4693
4887
  }
4694
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisWizardInlineNoticeComponent, decorators: [{
4888
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisWizardInlineNoticeComponent, decorators: [{
4695
4889
  type: Component,
4696
4890
  args: [{ selector: 'praxis-wizard-inline-notice', standalone: true, host: {
4697
4891
  '[attr.data-block-id]': 'blockId || null',
@@ -4711,22 +4905,26 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
4711
4905
  class PraxisWizardDividerComponent {
4712
4906
  blockId;
4713
4907
  label;
4714
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisWizardDividerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4715
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.17", type: PraxisWizardDividerComponent, isStandalone: true, selector: "praxis-wizard-divider", inputs: { blockId: "blockId", label: "label" }, host: { properties: { "attr.data-block-id": "blockId || null" } }, ngImport: i0, template: `
4908
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisWizardDividerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4909
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PraxisWizardDividerComponent, isStandalone: true, selector: "praxis-wizard-divider", inputs: { blockId: "blockId", label: "label" }, host: { properties: { "attr.data-block-id": "blockId || null" } }, ngImport: i0, template: `
4716
4910
  <div class="pwx-divider">
4717
- <span *ngIf="label" class="pwx-divider-label">{{ label }}</span>
4911
+ @if (label) {
4912
+ <span class="pwx-divider-label">{{ label }}</span>
4913
+ }
4718
4914
  </div>
4719
- `, isInline: true, styles: [":host{display:block}.pwx-divider{position:relative;height:1px;background:var(--praxis-wizard-divider, var(--md-sys-color-outline-variant));margin:16px 0}.pwx-divider-label{position:absolute;top:-.65rem;left:50%;transform:translate(-50%);padding:0 8px;font-size:.75rem;color:var(--praxis-wizard-muted, var(--md-sys-color-on-surface-variant));background:var(--praxis-wizard-card-bg, var(--md-sys-color-surface))}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4915
+ `, isInline: true, styles: [":host{display:block}.pwx-divider{position:relative;height:1px;background:var(--praxis-wizard-divider, var(--md-sys-color-outline-variant));margin:16px 0}.pwx-divider-label{position:absolute;top:-.65rem;left:50%;transform:translate(-50%);padding:0 8px;font-size:.75rem;color:var(--praxis-wizard-muted, var(--md-sys-color-on-surface-variant));background:var(--praxis-wizard-card-bg, var(--md-sys-color-surface))}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4720
4916
  }
4721
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisWizardDividerComponent, decorators: [{
4917
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisWizardDividerComponent, decorators: [{
4722
4918
  type: Component,
4723
4919
  args: [{ selector: 'praxis-wizard-divider', standalone: true, host: {
4724
4920
  '[attr.data-block-id]': 'blockId || null',
4725
- }, imports: [CommonModule], template: `
4921
+ }, imports: [], template: `
4726
4922
  <div class="pwx-divider">
4727
- <span *ngIf="label" class="pwx-divider-label">{{ label }}</span>
4923
+ @if (label) {
4924
+ <span class="pwx-divider-label">{{ label }}</span>
4925
+ }
4728
4926
  </div>
4729
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block}.pwx-divider{position:relative;height:1px;background:var(--praxis-wizard-divider, var(--md-sys-color-outline-variant));margin:16px 0}.pwx-divider-label{position:absolute;top:-.65rem;left:50%;transform:translate(-50%);padding:0 8px;font-size:.75rem;color:var(--praxis-wizard-muted, var(--md-sys-color-on-surface-variant));background:var(--praxis-wizard-card-bg, var(--md-sys-color-surface))}\n"] }]
4927
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block}.pwx-divider{position:relative;height:1px;background:var(--praxis-wizard-divider, var(--md-sys-color-outline-variant));margin:16px 0}.pwx-divider-label{position:absolute;top:-.65rem;left:50%;transform:translate(-50%);padding:0 8px;font-size:.75rem;color:var(--praxis-wizard-muted, var(--md-sys-color-on-surface-variant));background:var(--praxis-wizard-card-bg, var(--md-sys-color-surface))}\n"] }]
4730
4928
  }], propDecorators: { blockId: [{
4731
4929
  type: Input
4732
4930
  }], label: [{
@@ -5360,19 +5558,20 @@ class PraxisWizardCtaBarComponent {
5360
5558
  sticky = false;
5361
5559
  primaryClick = new EventEmitter();
5362
5560
  secondaryClick = new EventEmitter();
5363
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisWizardCtaBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
5364
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.17", type: PraxisWizardCtaBarComponent, isStandalone: true, selector: "praxis-wizard-cta-bar", inputs: { primaryLabel: "primaryLabel", primaryDisabled: "primaryDisabled", secondaryLabel: "secondaryLabel", showSecondary: "showSecondary", sticky: "sticky" }, outputs: { primaryClick: "primaryClick", secondaryClick: "secondaryClick" }, ngImport: i0, template: `
5561
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisWizardCtaBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
5562
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PraxisWizardCtaBarComponent, isStandalone: true, selector: "praxis-wizard-cta-bar", inputs: { primaryLabel: "primaryLabel", primaryDisabled: "primaryDisabled", secondaryLabel: "secondaryLabel", showSecondary: "showSecondary", sticky: "sticky" }, outputs: { primaryClick: "primaryClick", secondaryClick: "secondaryClick" }, ngImport: i0, template: `
5365
5563
  <div class="pwx-cta" [class.is-sticky]="sticky" [class.has-secondary]="showSecondary">
5366
- <button
5367
- *ngIf="showSecondary"
5368
- mat-button
5369
- type="button"
5370
- class="pwx-cta-secondary"
5371
- (click)="secondaryClick.emit()"
5372
- [attr.aria-label]="secondaryLabel"
5373
- >
5374
- {{ secondaryLabel }}
5375
- </button>
5564
+ @if (showSecondary) {
5565
+ <button
5566
+ mat-button
5567
+ type="button"
5568
+ class="pwx-cta-secondary"
5569
+ (click)="secondaryClick.emit()"
5570
+ [attr.aria-label]="secondaryLabel"
5571
+ >
5572
+ {{ secondaryLabel }}
5573
+ </button>
5574
+ }
5376
5575
  <button
5377
5576
  mat-flat-button
5378
5577
  color="primary"
@@ -5381,26 +5580,27 @@ class PraxisWizardCtaBarComponent {
5381
5580
  [disabled]="primaryDisabled"
5382
5581
  (click)="primaryClick.emit()"
5383
5582
  [attr.aria-label]="primaryLabel"
5384
- >
5583
+ >
5385
5584
  {{ primaryLabel }}
5386
5585
  </button>
5387
5586
  </div>
5388
- `, isInline: true, styles: [":host{display:block}.pwx-cta{display:flex;justify-content:flex-end;align-items:center;gap:12px;padding-top:16px}.pwx-cta:not(.has-secondary){justify-content:center}.pwx-cta.is-sticky{position:sticky;bottom:0;background:var(--praxis-wizard-card-bg, var(--md-sys-color-surface));padding:12px 0 8px;border-top:1px solid var(--praxis-wizard-border, var(--md-sys-color-outline-variant))}.pwx-cta.has-secondary .pwx-cta-primary{min-width:200px}.pwx-cta-primary{min-width:240px;height:36px;border-radius:4px;font-weight:600;text-transform:none;padding:0 18px}.pwx-cta-secondary{color:var(--praxis-wizard-muted, var(--md-sys-color-on-surface-variant));text-transform:none;font-weight:500;padding:0 4px;min-width:auto}@media(max-width:600px){.pwx-cta{flex-direction:column;align-items:stretch}.pwx-cta-primary{width:100%}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3$1.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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
5587
+ `, isInline: true, styles: [":host{display:block}.pwx-cta{display:flex;justify-content:flex-end;align-items:center;gap:12px;padding-top:16px}.pwx-cta:not(.has-secondary){justify-content:center}.pwx-cta.is-sticky{position:sticky;bottom:0;background:var(--praxis-wizard-card-bg, var(--md-sys-color-surface));padding:12px 0 8px;border-top:1px solid var(--praxis-wizard-border, var(--md-sys-color-outline-variant))}.pwx-cta.has-secondary .pwx-cta-primary{min-width:200px}.pwx-cta-primary{min-width:240px;height:36px;border-radius:4px;font-weight:600;text-transform:none;padding:0 18px}.pwx-cta-secondary{color:var(--praxis-wizard-muted, var(--md-sys-color-on-surface-variant));text-transform:none;font-weight:500;padding:0 4px;min-width:auto}@media(max-width:600px){.pwx-cta{flex-direction:column;align-items:stretch}.pwx-cta-primary{width:100%}}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3$1.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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
5389
5588
  }
5390
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisWizardCtaBarComponent, decorators: [{
5589
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisWizardCtaBarComponent, decorators: [{
5391
5590
  type: Component,
5392
- args: [{ selector: 'praxis-wizard-cta-bar', standalone: true, imports: [CommonModule, MatButtonModule], template: `
5591
+ args: [{ selector: 'praxis-wizard-cta-bar', standalone: true, imports: [MatButtonModule], template: `
5393
5592
  <div class="pwx-cta" [class.is-sticky]="sticky" [class.has-secondary]="showSecondary">
5394
- <button
5395
- *ngIf="showSecondary"
5396
- mat-button
5397
- type="button"
5398
- class="pwx-cta-secondary"
5399
- (click)="secondaryClick.emit()"
5400
- [attr.aria-label]="secondaryLabel"
5401
- >
5402
- {{ secondaryLabel }}
5403
- </button>
5593
+ @if (showSecondary) {
5594
+ <button
5595
+ mat-button
5596
+ type="button"
5597
+ class="pwx-cta-secondary"
5598
+ (click)="secondaryClick.emit()"
5599
+ [attr.aria-label]="secondaryLabel"
5600
+ >
5601
+ {{ secondaryLabel }}
5602
+ </button>
5603
+ }
5404
5604
  <button
5405
5605
  mat-flat-button
5406
5606
  color="primary"
@@ -5409,11 +5609,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
5409
5609
  [disabled]="primaryDisabled"
5410
5610
  (click)="primaryClick.emit()"
5411
5611
  [attr.aria-label]="primaryLabel"
5412
- >
5612
+ >
5413
5613
  {{ primaryLabel }}
5414
5614
  </button>
5415
5615
  </div>
5416
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block}.pwx-cta{display:flex;justify-content:flex-end;align-items:center;gap:12px;padding-top:16px}.pwx-cta:not(.has-secondary){justify-content:center}.pwx-cta.is-sticky{position:sticky;bottom:0;background:var(--praxis-wizard-card-bg, var(--md-sys-color-surface));padding:12px 0 8px;border-top:1px solid var(--praxis-wizard-border, var(--md-sys-color-outline-variant))}.pwx-cta.has-secondary .pwx-cta-primary{min-width:200px}.pwx-cta-primary{min-width:240px;height:36px;border-radius:4px;font-weight:600;text-transform:none;padding:0 18px}.pwx-cta-secondary{color:var(--praxis-wizard-muted, var(--md-sys-color-on-surface-variant));text-transform:none;font-weight:500;padding:0 4px;min-width:auto}@media(max-width:600px){.pwx-cta{flex-direction:column;align-items:stretch}.pwx-cta-primary{width:100%}}\n"] }]
5616
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block}.pwx-cta{display:flex;justify-content:flex-end;align-items:center;gap:12px;padding-top:16px}.pwx-cta:not(.has-secondary){justify-content:center}.pwx-cta.is-sticky{position:sticky;bottom:0;background:var(--praxis-wizard-card-bg, var(--md-sys-color-surface));padding:12px 0 8px;border-top:1px solid var(--praxis-wizard-border, var(--md-sys-color-outline-variant))}.pwx-cta.has-secondary .pwx-cta-primary{min-width:200px}.pwx-cta-primary{min-width:240px;height:36px;border-radius:4px;font-weight:600;text-transform:none;padding:0 18px}.pwx-cta-secondary{color:var(--praxis-wizard-muted, var(--md-sys-color-on-surface-variant));text-transform:none;font-weight:500;padding:0 4px;min-width:auto}@media(max-width:600px){.pwx-cta{flex-direction:column;align-items:stretch}.pwx-cta-primary{width:100%}}\n"] }]
5417
5617
  }], propDecorators: { primaryLabel: [{
5418
5618
  type: Input
5419
5619
  }], primaryDisabled: [{
@@ -5504,9 +5704,9 @@ class PraxisWizardFormComponent {
5504
5704
  submit = new EventEmitter();
5505
5705
  completed = this.submit;
5506
5706
  customAction = new EventEmitter();
5507
- _config = signal(null, ...(ngDevMode ? [{ debugName: "_config" }] : []));
5508
- persistedState = signal(null, ...(ngDevMode ? [{ debugName: "persistedState" }] : []));
5509
- selectedIndex = signal(0, ...(ngDevMode ? [{ debugName: "selectedIndex" }] : []));
5707
+ _config = signal(null, ...(ngDevMode ? [{ debugName: "_config" }] : /* istanbul ignore next */ []));
5708
+ persistedState = signal(null, ...(ngDevMode ? [{ debugName: "persistedState" }] : /* istanbul ignore next */ []));
5709
+ selectedIndex = signal(0, ...(ngDevMode ? [{ debugName: "selectedIndex" }] : /* istanbul ignore next */ []));
5510
5710
  wizard = computed(() => {
5511
5711
  const cfg = this._config();
5512
5712
  if (!cfg)
@@ -5515,28 +5715,28 @@ class PraxisWizardFormComponent {
5515
5715
  if (!persisted)
5516
5716
  return cfg;
5517
5717
  return applyPreferenceDefaults(cfg, persisted);
5518
- }, ...(ngDevMode ? [{ debugName: "wizard" }] : []));
5718
+ }, ...(ngDevMode ? [{ debugName: "wizard" }] : /* istanbul ignore next */ []));
5519
5719
  stepperConfig = computed(() => {
5520
5720
  const cfg = this.wizard();
5521
5721
  return cfg ? buildStepperConfig(cfg) : null;
5522
- }, ...(ngDevMode ? [{ debugName: "stepperConfig" }] : []));
5722
+ }, ...(ngDevMode ? [{ debugName: "stepperConfig" }] : /* istanbul ignore next */ []));
5523
5723
  activeStep = computed(() => {
5524
5724
  const w = this.wizard();
5525
5725
  return w?.steps?.[this.selectedIndex()] || null;
5526
- }, ...(ngDevMode ? [{ debugName: "activeStep" }] : []));
5527
- wizardBrand = computed(() => this.wizard()?.brand || 'PRAXIS UI', ...(ngDevMode ? [{ debugName: "wizardBrand" }] : []));
5528
- activeTitle = computed(() => this.activeStep()?.title || this.wizard()?.title || '', ...(ngDevMode ? [{ debugName: "activeTitle" }] : []));
5529
- activeSubtitle = computed(() => this.activeStep()?.subtitle || this.wizard()?.subtitle || '', ...(ngDevMode ? [{ debugName: "activeSubtitle" }] : []));
5530
- activeDescription = computed(() => this.activeStep()?.description || this.wizard()?.description || '', ...(ngDevMode ? [{ debugName: "activeDescription" }] : []));
5726
+ }, ...(ngDevMode ? [{ debugName: "activeStep" }] : /* istanbul ignore next */ []));
5727
+ wizardBrand = computed(() => this.wizard()?.brand || 'PRAXIS UI', ...(ngDevMode ? [{ debugName: "wizardBrand" }] : /* istanbul ignore next */ []));
5728
+ activeTitle = computed(() => this.activeStep()?.title || this.wizard()?.title || '', ...(ngDevMode ? [{ debugName: "activeTitle" }] : /* istanbul ignore next */ []));
5729
+ activeSubtitle = computed(() => this.activeStep()?.subtitle || this.wizard()?.subtitle || '', ...(ngDevMode ? [{ debugName: "activeSubtitle" }] : /* istanbul ignore next */ []));
5730
+ activeDescription = computed(() => this.activeStep()?.description || this.wizard()?.description || '', ...(ngDevMode ? [{ debugName: "activeDescription" }] : /* istanbul ignore next */ []));
5531
5731
  resolvedCta = computed(() => {
5532
5732
  const stepCta = this.activeStep()?.cta;
5533
5733
  const globalCta = this.wizard()?.cta;
5534
5734
  return { ...(globalCta || {}), ...(stepCta || {}) };
5535
- }, ...(ngDevMode ? [{ debugName: "resolvedCta" }] : []));
5536
- primaryLabel = computed(() => this.resolvedCta().label ?? 'Continue', ...(ngDevMode ? [{ debugName: "primaryLabel" }] : []));
5537
- primaryAction = computed(() => this.resolvedCta().action ?? 'next', ...(ngDevMode ? [{ debugName: "primaryAction" }] : []));
5538
- secondaryLabel = computed(() => this.resolvedCta().secondaryLabel ?? 'Back', ...(ngDevMode ? [{ debugName: "secondaryLabel" }] : []));
5539
- secondaryAction = computed(() => this.resolvedCta().secondaryAction ?? 'prev', ...(ngDevMode ? [{ debugName: "secondaryAction" }] : []));
5735
+ }, ...(ngDevMode ? [{ debugName: "resolvedCta" }] : /* istanbul ignore next */ []));
5736
+ primaryLabel = computed(() => this.resolvedCta().label ?? 'Continue', ...(ngDevMode ? [{ debugName: "primaryLabel" }] : /* istanbul ignore next */ []));
5737
+ primaryAction = computed(() => this.resolvedCta().action ?? 'next', ...(ngDevMode ? [{ debugName: "primaryAction" }] : /* istanbul ignore next */ []));
5738
+ secondaryLabel = computed(() => this.resolvedCta().secondaryLabel ?? 'Back', ...(ngDevMode ? [{ debugName: "secondaryLabel" }] : /* istanbul ignore next */ []));
5739
+ secondaryAction = computed(() => this.resolvedCta().secondaryAction ?? 'prev', ...(ngDevMode ? [{ debugName: "secondaryAction" }] : /* istanbul ignore next */ []));
5540
5740
  showSecondaryAction() {
5541
5741
  const action = this.secondaryAction();
5542
5742
  if (action === 'cancel')
@@ -5661,8 +5861,8 @@ class PraxisWizardFormComponent {
5661
5861
  const el = host.querySelector('.pwx-cta-secondary');
5662
5862
  el?.focus();
5663
5863
  }
5664
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisWizardFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
5665
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.17", type: PraxisWizardFormComponent, isStandalone: true, selector: "praxis-wizard-form", inputs: { wizardId: "wizardId", enableCustomization: "enableCustomization", config: "config" }, outputs: { submit: "submit", completed: "completed", customAction: "customAction" }, viewQueries: [{ propertyName: "stepper", first: true, predicate: ["stepper"], descendants: true, static: true }], ngImport: i0, template: `
5864
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisWizardFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
5865
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PraxisWizardFormComponent, isStandalone: true, selector: "praxis-wizard-form", inputs: { wizardId: "wizardId", enableCustomization: "enableCustomization", config: "config" }, outputs: { submit: "submit", completed: "completed", customAction: "customAction" }, viewQueries: [{ propertyName: "stepper", first: true, predicate: ["stepper"], descendants: true, static: true }], ngImport: i0, template: `
5666
5866
  <section class="ft-wizard-shell" [attr.data-wizard-id]="wizardId">
5667
5867
  <div class="ft-wizard-header">
5668
5868
  <div class="ft-brand">{{ wizardBrand() }}</div>
@@ -5700,11 +5900,11 @@ class PraxisWizardFormComponent {
5700
5900
  ></praxis-wizard-cta-bar>
5701
5901
  </mat-card>
5702
5902
  </section>
5703
- `, isInline: true, styles: [":host{display:block;min-height:100vh;background:var(--md-sys-color-surface-container-low);color:var(--md-sys-color-on-surface);font-family:\"Source Sans 3\",Segoe UI,system-ui,-apple-system,sans-serif;--praxis-wizard-accent: var(--md-sys-color-primary);--praxis-wizard-accent-on: var(--md-sys-color-on-primary);--praxis-wizard-muted: var(--md-sys-color-on-surface-variant);--praxis-wizard-card-bg: var(--md-sys-color-surface);--praxis-wizard-border: var(--md-sys-color-outline-variant);--pfx-section-gap: 12px;--pfx-form-section-surface: var(--md-sys-color-surface);--pfx-form-stroke: var(--md-sys-color-outline-variant)}.ft-wizard-shell{max-width:700px;margin:0 auto;padding:28px 16px 64px;display:flex;flex-direction:column;gap:12px}.ft-wizard-header{text-align:center;border-bottom:var(--ft-header-border, none);padding-bottom:var(--ft-header-spacing, 0px);margin-bottom:var(--ft-header-spacing, 0px)}.ft-brand{font-family:Iowan Old Style,Palatino Linotype,Book Antiqua,Palatino,serif;letter-spacing:.22em;font-size:17px;text-transform:uppercase;color:var(--md-sys-color-on-surface)}.ft-wizard-card{padding:20px 22px 16px;border-radius:var(--ft-radius, 10px);box-shadow:var(--ft-shadow, 0 6px 16px rgba(33, 24, 16, .05));border:1px solid var(--praxis-wizard-border);background:var(--praxis-wizard-card-bg)}:host ::ng-deep .ft-stepper{background:transparent}:host ::ng-deep .ft-stepper .mat-stepper-horizontal{background:transparent}:host ::ng-deep .ft-stepper-content{display:grid;gap:10px;padding-bottom:12px}:host ::ng-deep .ft-stepper-content .form-section{border:none!important;border-radius:0;background:transparent;padding:0;box-shadow:none!important}:host ::ng-deep .ft-stepper-content .form-section:focus-within{border-color:var(--pfx-form-stroke);box-shadow:none}:host ::ng-deep .ft-stepper-content .mat-mdc-form-field{width:100%;--mdc-outlined-text-field-container-height: 40px;--mdc-outlined-text-field-container-shape: var(--ft-radius, 4px);--mdc-outlined-text-field-outline-color: var(--md-sys-color-outline-variant);--mdc-outlined-text-field-focus-outline-color: var(--praxis-wizard-accent)}.ft-card-header h2{margin:0;font-family:var(--ft-font-head, inherit);font-size:1.32rem;font-weight:600;color:var(--md-sys-color-on-surface)}:host ::ng-deep .ft-stepper-content .mat-mdc-form-field-subscript-wrapper{margin-top:4px}:host ::ng-deep .ft-stepper-content .mat-mdc-floating-label,:host ::ng-deep .ft-stepper-content .mat-mdc-form-field-label{font-size:.88rem}:host ::ng-deep .ft-stepper-content .mat-mdc-form-field-hint,:host ::ng-deep .ft-stepper-content .mat-mdc-form-field-error{font-size:.78rem}:host ::ng-deep .ft-stepper-content .mat-mdc-checkbox,:host ::ng-deep .ft-stepper-content .mat-mdc-slide-toggle{margin:4px 0}:host ::ng-deep .ft-stepper-content .mat-mdc-slide-toggle .mdc-form-field,:host ::ng-deep .ft-stepper-content .mat-mdc-checkbox .mdc-form-field{gap:10px}:host ::ng-deep .ft-stepper-content .pdx-checkbox-group-wrapper{display:flex;flex-direction:column;gap:4px}:host ::ng-deep .ft-stepper-content .pdx-checkbox-label{font-size:.82rem;font-weight:600;color:var(--md-sys-color-on-surface);margin-bottom:2px}:host ::ng-deep .ft-stepper-content .pdx-checkbox-options{display:flex;flex-direction:column;gap:4px}:host ::ng-deep .ft-stepper-content .pdx-checkbox-options.pdx-checkbox-horizontal{flex-direction:row;flex-wrap:wrap;gap:12px}:host ::ng-deep .ft-stepper-content .pdx-slide-toggle-wrapper{min-height:32px;padding:0}:host ::ng-deep .ft-stepper-content .mat-mdc-slide-toggle{--mdc-switch-handle-height: 16px;--mdc-switch-handle-width: 16px;--mdc-switch-track-height: 20px;--mdc-switch-track-width: 36px}:host ::ng-deep .ft-stepper-content .pdx-slide-toggle-wrapper mat-slide-toggle{justify-content:space-between}:host ::ng-deep .ft-stepper-content .praxis-dynamic-form{display:block}:host ::ng-deep .ft-stepper-content .form-column{display:grid;align-content:start;gap:10px}:host ::ng-deep .ft-stepper-content .form-row{margin-bottom:0!important}:host ::ng-deep .ft-stepper-content .form-column>:is(.pdx-checkbox-group-wrapper,.pdx-slide-toggle-wrapper)+:is(.pdx-checkbox-group-wrapper,.pdx-slide-toggle-wrapper){padding-top:2px;border-top:1px solid var(--pfx-form-stroke)}:host ::ng-deep .ft-stepper-content .pdx-hint,:host ::ng-deep .ft-stepper-content .pdx-error{font-size:.78rem;color:var(--praxis-wizard-muted, var(--md-sys-color-on-surface-variant))}.ft-card-header{display:flex;flex-direction:column;gap:6px;margin-bottom:6px}.ft-card-header h2{margin:0;font-size:1.32rem;font-weight:600;color:var(--md-sys-color-on-surface)}.ft-card-header p{margin:0;color:var(--praxis-wizard-muted);font-size:.88rem}.ft-card-description{font-size:.84rem}.ft-card-description{color:var(--praxis-wizard-muted);font-size:.88rem}:host ::ng-deep .ft-card-title{font-weight:600;color:var(--md-sys-color-on-surface)}:host ::ng-deep .ft-card-desc{color:var(--praxis-wizard-muted);font-size:.84rem}@media(max-width:600px){.ft-wizard-shell{padding:22px 12px 48px}.ft-wizard-card{padding:16px 14px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i1$2.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: PraxisStepper, selector: "praxis-stepper", inputs: ["stepperId", "componentInstanceId", "config", "selectedIndexInput", "selectedIndex", "disableRippleInput", "enableCustomization", "labelPosition", "color", "serverValidate", "stepperContext"], outputs: ["selectedIndexChange", "widgetEvent", "stepFormReady", "stepFormValueChange", "animationDone", "selectionChange"] }, { kind: "component", type: PraxisWizardCtaBarComponent, selector: "praxis-wizard-cta-bar", inputs: ["primaryLabel", "primaryDisabled", "secondaryLabel", "showSecondary", "sticky"], outputs: ["primaryClick", "secondaryClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
5903
+ `, isInline: true, styles: [":host{display:block;min-height:100vh;background:var(--md-sys-color-surface-container-low);color:var(--md-sys-color-on-surface);font-family:\"Source Sans 3\",Segoe UI,system-ui,-apple-system,sans-serif;--praxis-wizard-accent: var(--md-sys-color-primary);--praxis-wizard-accent-on: var(--md-sys-color-on-primary);--praxis-wizard-muted: var(--md-sys-color-on-surface-variant);--praxis-wizard-card-bg: var(--md-sys-color-surface);--praxis-wizard-border: var(--md-sys-color-outline-variant);--pfx-section-gap: 12px;--pfx-form-section-surface: var(--md-sys-color-surface);--pfx-form-stroke: var(--md-sys-color-outline-variant)}.ft-wizard-shell{max-width:700px;margin:0 auto;padding:28px 16px 64px;display:flex;flex-direction:column;gap:12px}.ft-wizard-header{text-align:center;border-bottom:var(--ft-header-border, none);padding-bottom:var(--ft-header-spacing, 0px);margin-bottom:var(--ft-header-spacing, 0px)}.ft-brand{font-family:Iowan Old Style,Palatino Linotype,Book Antiqua,Palatino,serif;letter-spacing:.22em;font-size:17px;text-transform:uppercase;color:var(--md-sys-color-on-surface)}.ft-wizard-card{padding:20px 22px 16px;border-radius:var(--ft-radius, 10px);box-shadow:var(--ft-shadow, 0 6px 16px rgba(33, 24, 16, .05));border:1px solid var(--praxis-wizard-border);background:var(--praxis-wizard-card-bg)}:host ::ng-deep .ft-stepper{background:transparent}:host ::ng-deep .ft-stepper .mat-stepper-horizontal{background:transparent}:host ::ng-deep .ft-stepper-content{display:grid;gap:10px;padding-bottom:12px}:host ::ng-deep .ft-stepper-content .form-section{border:none!important;border-radius:0;background:transparent;padding:0;box-shadow:none!important}:host ::ng-deep .ft-stepper-content .form-section:focus-within{border-color:var(--pfx-form-stroke);box-shadow:none}:host ::ng-deep .ft-stepper-content .mat-mdc-form-field{width:100%;--mdc-outlined-text-field-container-height: 40px;--mdc-outlined-text-field-container-shape: var(--ft-radius, 4px);--mdc-outlined-text-field-outline-color: var(--md-sys-color-outline-variant);--mdc-outlined-text-field-focus-outline-color: var(--praxis-wizard-accent)}.ft-card-header h2{margin:0;font-family:var(--ft-font-head, inherit);font-size:1.32rem;font-weight:600;color:var(--md-sys-color-on-surface)}:host ::ng-deep .ft-stepper-content .mat-mdc-form-field-subscript-wrapper{margin-top:4px}:host ::ng-deep .ft-stepper-content .mat-mdc-floating-label,:host ::ng-deep .ft-stepper-content .mat-mdc-form-field-label{font-size:.88rem}:host ::ng-deep .ft-stepper-content .mat-mdc-form-field-hint,:host ::ng-deep .ft-stepper-content .mat-mdc-form-field-error{font-size:.78rem}:host ::ng-deep .ft-stepper-content .mat-mdc-checkbox,:host ::ng-deep .ft-stepper-content .mat-mdc-slide-toggle{margin:4px 0}:host ::ng-deep .ft-stepper-content .mat-mdc-slide-toggle .mdc-form-field,:host ::ng-deep .ft-stepper-content .mat-mdc-checkbox .mdc-form-field{gap:10px}:host ::ng-deep .ft-stepper-content .pdx-checkbox-group-wrapper{display:flex;flex-direction:column;gap:4px}:host ::ng-deep .ft-stepper-content .pdx-checkbox-label{font-size:.82rem;font-weight:600;color:var(--md-sys-color-on-surface);margin-bottom:2px}:host ::ng-deep .ft-stepper-content .pdx-checkbox-options{display:flex;flex-direction:column;gap:4px}:host ::ng-deep .ft-stepper-content .pdx-checkbox-options.pdx-checkbox-horizontal{flex-direction:row;flex-wrap:wrap;gap:12px}:host ::ng-deep .ft-stepper-content .pdx-slide-toggle-wrapper{min-height:32px;padding:0}:host ::ng-deep .ft-stepper-content .mat-mdc-slide-toggle{--mdc-switch-handle-height: 16px;--mdc-switch-handle-width: 16px;--mdc-switch-track-height: 20px;--mdc-switch-track-width: 36px}:host ::ng-deep .ft-stepper-content .pdx-slide-toggle-wrapper mat-slide-toggle{justify-content:space-between}:host ::ng-deep .ft-stepper-content .praxis-dynamic-form{display:block}:host ::ng-deep .ft-stepper-content .form-column{display:grid;align-content:start;gap:10px}:host ::ng-deep .ft-stepper-content .form-row{margin-bottom:0!important}:host ::ng-deep .ft-stepper-content .form-column>:is(.pdx-checkbox-group-wrapper,.pdx-slide-toggle-wrapper)+:is(.pdx-checkbox-group-wrapper,.pdx-slide-toggle-wrapper){padding-top:2px;border-top:1px solid var(--pfx-form-stroke)}:host ::ng-deep .ft-stepper-content .pdx-hint,:host ::ng-deep .ft-stepper-content .pdx-error{font-size:.78rem;color:var(--praxis-wizard-muted, var(--md-sys-color-on-surface-variant))}.ft-card-header{display:flex;flex-direction:column;gap:6px;margin-bottom:6px}.ft-card-header h2{margin:0;font-size:1.32rem;font-weight:600;color:var(--md-sys-color-on-surface)}.ft-card-header p{margin:0;color:var(--praxis-wizard-muted);font-size:.88rem}.ft-card-description{font-size:.84rem}.ft-card-description{color:var(--praxis-wizard-muted);font-size:.88rem}:host ::ng-deep .ft-card-title{font-weight:600;color:var(--md-sys-color-on-surface)}:host ::ng-deep .ft-card-desc{color:var(--praxis-wizard-muted);font-size:.84rem}@media(max-width:600px){.ft-wizard-shell{padding:22px 12px 48px}.ft-wizard-card{padding:16px 14px}}\n"], dependencies: [{ kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i1$3.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: PraxisStepper, selector: "praxis-stepper", inputs: ["stepperId", "componentInstanceId", "config", "selectedIndexInput", "selectedIndex", "disableRippleInput", "enableCustomization", "labelPosition", "color", "serverValidate", "stepperContext"], outputs: ["selectedIndexChange", "widgetEvent", "stepFormReady", "stepFormValueChange", "animationDone", "selectionChange"] }, { kind: "component", type: PraxisWizardCtaBarComponent, selector: "praxis-wizard-cta-bar", inputs: ["primaryLabel", "primaryDisabled", "secondaryLabel", "showSecondary", "sticky"], outputs: ["primaryClick", "secondaryClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
5704
5904
  }
5705
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisWizardFormComponent, decorators: [{
5905
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisWizardFormComponent, decorators: [{
5706
5906
  type: Component,
5707
- args: [{ selector: 'praxis-wizard-form', standalone: true, imports: [CommonModule, MatCardModule, MatIconModule, PraxisStepper, PraxisWizardCtaBarComponent], template: `
5907
+ args: [{ selector: 'praxis-wizard-form', standalone: true, imports: [MatCardModule, MatIconModule, PraxisStepper, PraxisWizardCtaBarComponent], template: `
5708
5908
  <section class="ft-wizard-shell" [attr.data-wizard-id]="wizardId">
5709
5909
  <div class="ft-wizard-header">
5710
5910
  <div class="ft-brand">{{ wizardBrand() }}</div>