@praxisui/stepper 9.0.5-rc.12 → 9.0.5-rc.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -61,6 +61,8 @@ export class OnboardingComponent {
61
61
 
62
62
  Each step can host a `@praxisui/dynamic-form` configuration. Use canonical resource paths without `/api`, `/filter` or `/{id}`.
63
63
 
64
+ When the form uses an explicit request schema or API entry, pass `schemaUrl`, `apiEndpointKey` and `apiUrlEntry` in `step.form`; the stepper forwards them unchanged and never infers schema authority. It forwards metadata-only lifecycle as `stepReactiveDeterminationExecuted` and aggregate state as `stepReactiveDeterminationPendingChange`. Next and wizard submit remain blocked until the child form stabilizes (or remain blocked after timeout).
65
+
64
66
  ```ts
65
67
  const config: StepperMetadata = {
66
68
  linear: true,
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": "1.0.0",
3
- "generatedAt": "2026-08-13T13:48:00.302Z",
3
+ "generatedAt": "2026-08-13T20:07:32.063Z",
4
4
  "packageName": "@praxisui/stepper",
5
- "packageVersion": "9.0.5-rc.12",
5
+ "packageVersion": "9.0.5-rc.14",
6
6
  "sourceRegistry": "praxis-component-registry-ingestion",
7
7
  "sourceRegistryVersion": "1.0.0",
8
8
  "componentCount": 1,
@@ -121,6 +121,18 @@
121
121
  "type": "{ stepId?: string; stepIndex: number; event: FormValueChangeEvent }",
122
122
  "required": false,
123
123
  "label": "Form value change (por etapa)"
124
+ },
125
+ {
126
+ "name": "stepReactiveDeterminationExecuted",
127
+ "type": "{ stepId?: string; stepIndex: number; event: ReactiveDeterminationExecutionEvent }",
128
+ "required": false,
129
+ "label": "Evidencia metadata-only por etapa"
130
+ },
131
+ {
132
+ "name": "stepReactiveDeterminationPendingChange",
133
+ "type": "{ stepId?: string; stepIndex: number; pending: boolean }",
134
+ "required": false,
135
+ "label": "Estado de estabilizacao por etapa"
124
136
  }
125
137
  ],
126
138
  "configSchemaId": null,
@@ -2128,9 +2140,9 @@
2128
2140
  {
2129
2141
  "chunkIndex": 0,
2130
2142
  "chunkKind": "summary",
2131
- "content": "Component ID: praxis-stepper\nSelector: praxis-stepper\nFriendly Name: Praxis Stepper\nDescription: Stepper configurável (horizontal/vertical/linear) com passos e conteúdo dinâmico.\nLib/Package: @praxisui/stepper\nTags: widget, container, stepper, configurable\nInputs:\n - stepperId (string)\n - componentInstanceId (string)\n - config (StepperMetadata)\n - selectedIndex (number)\n - selectedIndexInput (number)\n - disableRippleInput (boolean)\n - enableCustomization (boolean)\n - labelPosition ('bottom' | 'end')\n - color (ThemePalette)\n - serverValidate ((args) => Promise<{ ok: boolean; fieldErrors?: Record<string,string[]>; formErrors?: string[] }>)\n - stepperContext (Record<string, any>)\nOutputs:\n - selectionChange (any)\n - selectedIndexChange (number)\n - animationDone (void)\n - widgetEvent (WidgetEventEnvelope)\n - stepFormReady ({ stepId?: string; stepIndex: number; event: FormReadyEvent })\n - stepFormValueChange ({ stepId?: string; stepIndex: number; event: FormValueChangeEvent })\n",
2143
+ "content": "Component ID: praxis-stepper\nSelector: praxis-stepper\nFriendly Name: Praxis Stepper\nDescription: Stepper configurável (horizontal/vertical/linear) com passos e conteúdo dinâmico.\nLib/Package: @praxisui/stepper\nTags: widget, container, stepper, configurable\nInputs:\n - stepperId (string)\n - componentInstanceId (string)\n - config (StepperMetadata)\n - selectedIndex (number)\n - selectedIndexInput (number)\n - disableRippleInput (boolean)\n - enableCustomization (boolean)\n - labelPosition ('bottom' | 'end')\n - color (ThemePalette)\n - serverValidate ((args) => Promise<{ ok: boolean; fieldErrors?: Record<string,string[]>; formErrors?: string[] }>)\n - stepperContext (Record<string, any>)\nOutputs:\n - selectionChange (any)\n - selectedIndexChange (number)\n - animationDone (void)\n - widgetEvent (WidgetEventEnvelope)\n - stepFormReady ({ stepId?: string; stepIndex: number; event: FormReadyEvent })\n - stepFormValueChange ({ stepId?: string; stepIndex: number; event: FormValueChangeEvent })\n - stepReactiveDeterminationExecuted ({ stepId?: string; stepIndex: number; event: ReactiveDeterminationExecutionEvent })\n - stepReactiveDeterminationPendingChange ({ stepId?: string; stepIndex: number; pending: boolean })\n",
2132
2144
  "sourcePointer": "projects/praxis-stepper/src/lib/praxis-stepper.metadata.ts",
2133
- "contentHash": "d753191bcc0a9e88df19ce2d3becb8dbc928e8c22db0d488dcfcdde2381c8e79",
2145
+ "contentHash": "89fa6ee9abc0b7a70beb7bdf1692cdf4a53fbded066cca36874f736e7ba5903a",
2134
2146
  "sourceKind": "component_definition",
2135
2147
  "sourceId": "praxis-stepper",
2136
2148
  "corpusVersion": "1.0.0"
@@ -3414,11 +3414,14 @@ class StepperAgenticAuthoringTurnFlow {
3414
3414
  class PraxisStepper {
3415
3415
  // Templates projetados
3416
3416
  stepLabelTpl;
3417
+ materialStepper;
3417
3418
  // Dados e estado
3418
3419
  _config = signal(null, ...(ngDevMode ? [{ debugName: "_config" }] : /* istanbul ignore next */ []));
3419
3420
  _selectedIndex = signal(0, ...(ngDevMode ? [{ debugName: "_selectedIndex" }] : /* istanbul ignore next */ []));
3420
3421
  _formGroups = new Map();
3422
+ _formComponents = new Map();
3421
3423
  _formValidity = new Map();
3424
+ _formPending = new Map();
3422
3425
  hostElement = inject((ElementRef));
3423
3426
  renderer = inject(Renderer2);
3424
3427
  appliedHeaderClasses = [];
@@ -3471,6 +3474,9 @@ class PraxisStepper {
3471
3474
  widgetEvent = new EventEmitter();
3472
3475
  stepFormReady = new EventEmitter();
3473
3476
  stepFormValueChange = new EventEmitter();
3477
+ /** Metadata-only determination lifecycle forwarded from the child form. */
3478
+ stepReactiveDeterminationExecuted = new EventEmitter();
3479
+ stepReactiveDeterminationPendingChange = new EventEmitter();
3474
3480
  stepperContext;
3475
3481
  settings = inject(SettingsPanelService);
3476
3482
  storage = inject(ASYNC_CONFIG_STORAGE);
@@ -3559,7 +3565,8 @@ class PraxisStepper {
3559
3565
  }
3560
3566
  };
3561
3567
  isNextDisabled(i) {
3562
- return this.linear() && this._formValidity.get(i) === false;
3568
+ return this._formPending.get(i) === true ||
3569
+ (this.linear() && this._formValidity.get(i) === false);
3563
3570
  }
3564
3571
  clampIndex(idx) {
3565
3572
  const len = this.steps().length;
@@ -3582,6 +3589,13 @@ class PraxisStepper {
3582
3589
  trackStep = (_, s) => s.id || _;
3583
3590
  onSelectionChange(ev) {
3584
3591
  const idx = this.clampIndex(ev?.selectedIndex ?? 0);
3592
+ const current = this._selectedIndex();
3593
+ if (idx !== current && this._formPending.get(current) === true) {
3594
+ if (this.materialStepper)
3595
+ this.materialStepper.selectedIndex = current;
3596
+ this.cdr.markForCheck();
3597
+ return;
3598
+ }
3585
3599
  this._selectedIndex.set(idx);
3586
3600
  this.selectedIndexChange.emit(idx);
3587
3601
  this.selectionChange.emit(ev);
@@ -3589,14 +3603,16 @@ class PraxisStepper {
3589
3603
  // API programática básica
3590
3604
  goTo(index) {
3591
3605
  const clamped = this.clampIndex(index);
3592
- this._selectedIndex.set(clamped);
3593
- this.selectedIndexChange.emit(clamped);
3606
+ if (clamped !== this._selectedIndex() && this._formPending.get(this._selectedIndex()) === true) {
3607
+ return;
3608
+ }
3609
+ this.advanceTo(clamped);
3594
3610
  }
3595
3611
  next() {
3596
3612
  const curr = this._selectedIndex();
3597
3613
  const len = this.steps().length;
3598
- if (curr < len - 1)
3599
- this.goTo(curr + 1);
3614
+ if (curr < len - 1 && this._formPending.get(curr) !== true)
3615
+ this.advanceTo(curr + 1);
3600
3616
  }
3601
3617
  prev() {
3602
3618
  const curr = this._selectedIndex();
@@ -3604,11 +3620,18 @@ class PraxisStepper {
3604
3620
  this.goTo(curr - 1);
3605
3621
  }
3606
3622
  reset() { this.goTo(0); }
3623
+ advanceTo(index) {
3624
+ const clamped = this.clampIndex(index);
3625
+ this._selectedIndex.set(clamped);
3626
+ this.selectedIndexChange.emit(clamped);
3627
+ }
3607
3628
  // Alias para compatibilidade nominal com MatStepper
3608
3629
  previous() { this.prev(); }
3609
3630
  // Dynamic Form integration
3610
- onFormReady(stepIndex, ev) {
3631
+ onFormReady(stepIndex, ev, component) {
3611
3632
  this._formGroups.set(stepIndex, ev.formGroup);
3633
+ if (component)
3634
+ this._formComponents.set(stepIndex, component);
3612
3635
  this._formValidity.set(stepIndex, ev.formGroup.valid);
3613
3636
  this.stepFormReady.emit({
3614
3637
  stepIndex,
@@ -3624,6 +3647,22 @@ class PraxisStepper {
3624
3647
  event: ev,
3625
3648
  });
3626
3649
  }
3650
+ onReactiveDeterminationExecuted(stepIndex, event) {
3651
+ this.stepReactiveDeterminationExecuted.emit({
3652
+ stepIndex,
3653
+ stepId: this.steps()[stepIndex]?.id,
3654
+ event,
3655
+ });
3656
+ }
3657
+ onReactiveDeterminationPendingChange(stepIndex, pending) {
3658
+ this._formPending.set(stepIndex, pending);
3659
+ this.stepReactiveDeterminationPendingChange.emit({
3660
+ stepIndex,
3661
+ stepId: this.steps()[stepIndex]?.id,
3662
+ pending,
3663
+ });
3664
+ this.cdr.markForCheck();
3665
+ }
3627
3666
  formGroupFor(i) {
3628
3667
  return this._formGroups.get(i);
3629
3668
  }
@@ -4034,6 +4073,12 @@ class PraxisStepper {
4034
4073
  await this.nextWithValidation(i);
4035
4074
  }
4036
4075
  async validateStep(i = this.selectedIndexComputed()) {
4076
+ const childForm = this._formComponents.get(i);
4077
+ if (childForm?.hasPendingReactiveDeterminations()) {
4078
+ const stable = await childForm.waitForReactiveDeterminations();
4079
+ if (!stable)
4080
+ return false;
4081
+ }
4037
4082
  // Em modo linear, bloquear quando inválido
4038
4083
  if (this.linear() && this._formValidity.get(i) === false) {
4039
4084
  const fg = this._formGroups.get(i);
@@ -4058,6 +4103,11 @@ class PraxisStepper {
4058
4103
  this._formValidity.set(i, false);
4059
4104
  return false;
4060
4105
  }
4106
+ if (childForm?.hasPendingReactiveDeterminations()) {
4107
+ const stable = await childForm.waitForReactiveDeterminations();
4108
+ if (!stable)
4109
+ return false;
4110
+ }
4061
4111
  }
4062
4112
  return true;
4063
4113
  }
@@ -4066,7 +4116,9 @@ class PraxisStepper {
4066
4116
  if (!isValid) {
4067
4117
  return false;
4068
4118
  }
4069
- this.next();
4119
+ const current = this._selectedIndex();
4120
+ if (current < this.steps().length - 1)
4121
+ this.advanceTo(current + 1);
4070
4122
  return true;
4071
4123
  }
4072
4124
  onPrev() { this.prev(); }
@@ -4190,7 +4242,7 @@ class PraxisStepper {
4190
4242
  return name.startsWith('--') ? name : `--${name}`;
4191
4243
  }
4192
4244
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisStepper, deps: [], target: i0.ɵɵFactoryTarget.Component });
4193
- 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: `
4245
+ 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", stepReactiveDeterminationExecuted: "stepReactiveDeterminationExecuted", stepReactiveDeterminationPendingChange: "stepReactiveDeterminationPendingChange", animationDone: "animationDone", selectionChange: "selectionChange" }, host: { properties: { "class": "densityClass()" } }, queries: [{ propertyName: "stepLabelTpl", first: true, predicate: ["stepLabelTpl"], descendants: true, read: TemplateRef }], viewQueries: [{ propertyName: "materialStepper", first: true, predicate: ["stepperRoot"], descendants: true }], ngImport: i0, template: `
4194
4246
  @if (enableCustomization) {
4195
4247
  <div class="stepper-ai-assistant">
4196
4248
  <button
@@ -4306,14 +4358,20 @@ class PraxisStepper {
4306
4358
  }
4307
4359
  @if (step.form; as f) {
4308
4360
  <praxis-dynamic-form
4361
+ #stepForm
4309
4362
  [resourcePath]="f.resourcePath"
4310
4363
  [resourceId]="$any(f.resourceId)"
4311
4364
  [mode]="f.mode || 'create'"
4312
4365
  [config]="f.config || { sections: [] }"
4313
4366
  [schemaSource]="f.schemaSource || 'resource'"
4367
+ [schemaUrl]="f.schemaUrl"
4368
+ [apiEndpointKey]="$any(f.apiEndpointKey)"
4369
+ [apiUrlEntry]="f.apiUrlEntry || null"
4314
4370
  [formId]="f.formId"
4315
- (formReady)="onFormReady(i, $event)"
4371
+ (formReady)="onFormReady(i, $event, stepForm)"
4316
4372
  (valueChange)="onFormValueChange(i, $event)"
4373
+ (reactiveDeterminationExecuted)="onReactiveDeterminationExecuted(i, $event)"
4374
+ (reactiveDeterminationPendingChange)="onReactiveDeterminationPendingChange(i, $event)"
4317
4375
  ></praxis-dynamic-form>
4318
4376
  }
4319
4377
  @if (hasRichContent(step.stepBlocksAfterForm)) {
@@ -4440,7 +4498,7 @@ class PraxisStepper {
4440
4498
  <mat-icon fontIcon="edit"></mat-icon>
4441
4499
  </button>
4442
4500
  }
4443
- `, 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", "readUrl", "submitUrl", "submitMethod", "submitIdempotencyKey", "submitCorrelationId", "submitResourceVersion", "responseSchemaUrl", "apiEndpointKey", "apiUrlEntry", "enableCustomization", "showAiAssistant", "formId", "componentInstanceId", "configPersistenceStrategy", "layout", "generatedLayoutPreset", "layoutPolicy", "backConfig", "hooks", "removeEmptyContainersOnSave", "reactiveValidation", "reactiveValidationDebounceMs", "notifyIfOutdated", "snoozeMs", "autoOpenSettingsOnOutdated", "readonlyModeGlobal", "disabledModeGlobal", "presentationModeGlobal", "visibleGlobal", "fieldIconPolicy", "domainRules", "customEndpoints"], outputs: ["formSubmit", "formCancel", "formReset", "configChange", "configPatchChange", "formReady", "valueChange", "syncCompleted", "initializationError", "loadingStateChange", "enableCustomizationChange", "customAction", "actionConfirmation", "schemaStatusChange", "fieldRenderError", "ruleDiagnosticsChange", "formEffectExecuted"] }, { 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", "variant", "alignment", "density", "iconContainer"] }, { kind: "component", type: PraxisAiAssistantShellComponent, selector: "praxis-ai-assistant-shell", inputs: ["labels", "mode", "state", "contextItems", "attachments", "messages", "quickReplies", "recommendedIntents", "prompt", "statusText", "errorText", "testIdPrefix", "panelTestId", "submitTestId", "applyTestId", "primaryAction", "secondaryActions", "governanceActions", "busy", "canSubmit", "canApply", "submitOnEnter", "showAttachAction", "enablePastedAttachments", "enableFileAttachments", "attachmentAccept", "attachmentMultiple", "voiceInputMode", "voiceLanguage", "draggable", "resizable", "minWidth", "minHeight", "margin", "layout"], outputs: ["promptChange", "submitPrompt", "apply", "retryTurn", "cancelTurn", "shellAction", "close", "attach", "attachmentsPasted", "attachmentsSelected", "removeAttachment", "messageAction", "editMessage", "resendMessage", "quickReply", "recommendedIntent", "layoutChange"] }, { kind: "component", type: PraxisRichContent, selector: "praxis-rich-content", inputs: ["document", "nodes", "context", "hostCapabilities", "layout", "rootClassName"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4501
+ `, 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", "readUrl", "submitUrl", "submitMethod", "submitIdempotencyKey", "submitCorrelationId", "submitResourceVersion", "responseSchemaUrl", "apiEndpointKey", "apiUrlEntry", "enableCustomization", "showAiAssistant", "formId", "componentInstanceId", "configPersistenceStrategy", "layout", "generatedLayoutPreset", "layoutPolicy", "backConfig", "hooks", "removeEmptyContainersOnSave", "reactiveValidation", "reactiveValidationDebounceMs", "notifyIfOutdated", "snoozeMs", "autoOpenSettingsOnOutdated", "readonlyModeGlobal", "disabledModeGlobal", "presentationModeGlobal", "visibleGlobal", "fieldIconPolicy", "domainRules", "customEndpoints"], outputs: ["formSubmit", "formCancel", "formReset", "configChange", "configPatchChange", "formReady", "valueChange", "syncCompleted", "initializationError", "loadingStateChange", "enableCustomizationChange", "customAction", "actionConfirmation", "schemaStatusChange", "fieldRenderError", "ruleDiagnosticsChange", "reactiveDeterminationExecuted", "reactiveDeterminationPendingChange"] }, { 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", "variant", "alignment", "density", "iconContainer"] }, { kind: "component", type: PraxisAiAssistantShellComponent, selector: "praxis-ai-assistant-shell", inputs: ["labels", "mode", "state", "contextItems", "attachments", "messages", "quickReplies", "recommendedIntents", "prompt", "statusText", "errorText", "testIdPrefix", "panelTestId", "submitTestId", "applyTestId", "primaryAction", "secondaryActions", "governanceActions", "busy", "canSubmit", "canApply", "submitOnEnter", "showAttachAction", "enablePastedAttachments", "enableFileAttachments", "attachmentAccept", "attachmentMultiple", "voiceInputMode", "voiceLanguage", "draggable", "resizable", "minWidth", "minHeight", "margin", "layout"], outputs: ["promptChange", "submitPrompt", "apply", "retryTurn", "cancelTurn", "shellAction", "close", "attach", "attachmentsPasted", "attachmentsSelected", "removeAttachment", "messageAction", "editMessage", "resendMessage", "quickReply", "recommendedIntent", "layoutChange"] }, { kind: "component", type: PraxisRichContent, selector: "praxis-rich-content", inputs: ["document", "nodes", "context", "hostCapabilities", "layout", "rootClassName"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4444
4502
  }
4445
4503
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisStepper, decorators: [{
4446
4504
  type: Component,
@@ -4562,14 +4620,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
4562
4620
  }
4563
4621
  @if (step.form; as f) {
4564
4622
  <praxis-dynamic-form
4623
+ #stepForm
4565
4624
  [resourcePath]="f.resourcePath"
4566
4625
  [resourceId]="$any(f.resourceId)"
4567
4626
  [mode]="f.mode || 'create'"
4568
4627
  [config]="f.config || { sections: [] }"
4569
4628
  [schemaSource]="f.schemaSource || 'resource'"
4629
+ [schemaUrl]="f.schemaUrl"
4630
+ [apiEndpointKey]="$any(f.apiEndpointKey)"
4631
+ [apiUrlEntry]="f.apiUrlEntry || null"
4570
4632
  [formId]="f.formId"
4571
- (formReady)="onFormReady(i, $event)"
4633
+ (formReady)="onFormReady(i, $event, stepForm)"
4572
4634
  (valueChange)="onFormValueChange(i, $event)"
4635
+ (reactiveDeterminationExecuted)="onReactiveDeterminationExecuted(i, $event)"
4636
+ (reactiveDeterminationPendingChange)="onReactiveDeterminationPendingChange(i, $event)"
4573
4637
  ></praxis-dynamic-form>
4574
4638
  }
4575
4639
  @if (hasRichContent(step.stepBlocksAfterForm)) {
@@ -4700,6 +4764,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
4700
4764
  }], propDecorators: { stepLabelTpl: [{
4701
4765
  type: ContentChild,
4702
4766
  args: ['stepLabelTpl', { read: TemplateRef }]
4767
+ }], materialStepper: [{
4768
+ type: ViewChild,
4769
+ args: ['stepperRoot']
4703
4770
  }], stepperId: [{
4704
4771
  type: Input,
4705
4772
  args: [{ required: true }]
@@ -4729,6 +4796,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
4729
4796
  type: Output
4730
4797
  }], stepFormValueChange: [{
4731
4798
  type: Output
4799
+ }], stepReactiveDeterminationExecuted: [{
4800
+ type: Output
4801
+ }], stepReactiveDeterminationPendingChange: [{
4802
+ type: Output
4732
4803
  }], stepperContext: [{
4733
4804
  type: Input
4734
4805
  }], animationDone: [{
@@ -5045,6 +5116,8 @@ const PRAXIS_STEPPER_COMPONENT_METADATA = {
5045
5116
  { name: 'widgetEvent', type: 'WidgetEventEnvelope', label: 'Evento interno' },
5046
5117
  { name: 'stepFormReady', type: '{ stepId?: string; stepIndex: number; event: FormReadyEvent }', label: 'Form ready (por etapa)' },
5047
5118
  { name: 'stepFormValueChange', type: '{ stepId?: string; stepIndex: number; event: FormValueChangeEvent }', label: 'Form value change (por etapa)' },
5119
+ { name: 'stepReactiveDeterminationExecuted', type: '{ stepId?: string; stepIndex: number; event: ReactiveDeterminationExecutionEvent }', label: 'Evidencia metadata-only por etapa' },
5120
+ { name: 'stepReactiveDeterminationPendingChange', type: '{ stepId?: string; stepIndex: number; pending: boolean }', label: 'Estado de estabilizacao por etapa' },
5048
5121
  ],
5049
5122
  actions: [
5050
5123
  {
@@ -5492,7 +5565,13 @@ function buildStep(step, wizardId) {
5492
5565
  ? {
5493
5566
  formId: step.form.formId || `${wizardId}:${step.id}`,
5494
5567
  config: step.form.config,
5495
- mode: 'create',
5568
+ resourcePath: step.form.resourcePath,
5569
+ resourceId: step.form.resourceId,
5570
+ mode: step.form.mode || 'create',
5571
+ schemaSource: step.form.schemaSource,
5572
+ schemaUrl: step.form.schemaUrl,
5573
+ apiEndpointKey: step.form.apiEndpointKey,
5574
+ apiUrlEntry: step.form.apiUrlEntry,
5496
5575
  }
5497
5576
  : undefined,
5498
5577
  };
@@ -5974,7 +6053,7 @@ class PraxisWizardFormComponent {
5974
6053
  ></praxis-wizard-cta-bar>
5975
6054
  </mat-card>
5976
6055
  </section>
5977
- `, 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 });
6056
+ `, 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", "stepReactiveDeterminationExecuted", "stepReactiveDeterminationPendingChange", "animationDone", "selectionChange"] }, { kind: "component", type: PraxisWizardCtaBarComponent, selector: "praxis-wizard-cta-bar", inputs: ["primaryLabel", "primaryDisabled", "secondaryLabel", "showSecondary", "sticky"], outputs: ["primaryClick", "secondaryClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
5978
6057
  }
5979
6058
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisWizardFormComponent, decorators: [{
5980
6059
  type: Component,
package/package.json CHANGED
@@ -1,22 +1,22 @@
1
1
  {
2
2
  "name": "@praxisui/stepper",
3
- "version": "9.0.5-rc.12",
3
+ "version": "9.0.5-rc.14",
4
4
  "description": "Stepper workflows for Praxis UI with integrated forms, lists, uploads and page builder support.",
5
5
  "peerDependencies": {
6
6
  "@angular/common": "^21.0.0",
7
7
  "@angular/core": "^21.0.0",
8
8
  "@angular/material": "^21.0.0",
9
9
  "@angular/cdk": "^21.0.0",
10
- "@praxisui/core": "^9.0.5-rc.12",
11
- "@praxisui/dynamic-form": "^9.0.5-rc.12",
12
- "@praxisui/rich-content": "^9.0.5-rc.12",
13
- "@praxisui/settings-panel": "^9.0.5-rc.12",
14
- "@praxisui/list": "^9.0.5-rc.12",
15
- "@praxisui/files-upload": "^9.0.5-rc.12",
16
- "@praxisui/page-builder": "^9.0.5-rc.12",
10
+ "@praxisui/core": "^9.0.5-rc.14",
11
+ "@praxisui/dynamic-form": "^9.0.5-rc.14",
12
+ "@praxisui/rich-content": "^9.0.5-rc.14",
13
+ "@praxisui/settings-panel": "^9.0.5-rc.14",
14
+ "@praxisui/list": "^9.0.5-rc.14",
15
+ "@praxisui/files-upload": "^9.0.5-rc.14",
16
+ "@praxisui/page-builder": "^9.0.5-rc.14",
17
17
  "@angular/forms": "^21.0.0",
18
18
  "@angular/router": "^21.0.0",
19
- "@praxisui/ai": "^9.0.5-rc.12",
19
+ "@praxisui/ai": "^9.0.5-rc.14",
20
20
  "rxjs": "~7.8.0"
21
21
  },
22
22
  "dependencies": {
@@ -1,7 +1,8 @@
1
1
  import * as _angular_core from '@angular/core';
2
2
  import { OnInit, AfterViewInit, OnDestroy, TemplateRef, EventEmitter, Provider } from '@angular/core';
3
- import { AiCapability, FormConfig, RichContentDocument, WidgetDefinition, WidgetEventEnvelope, FormReadyEvent, FormValueChangeEvent, JsonLogicRecord, ComponentDocMeta, SettingsValueProvider as SettingsValueProvider$1, AiCapabilityCategory, AiCapabilityCatalog, AiValueKind, ComponentAuthoringManifest } from '@praxisui/core';
3
+ import { AiCapability, FormConfig, ApiEndpoint, ApiUrlEntry, RichContentDocument, WidgetDefinition, WidgetEventEnvelope, FormReadyEvent, FormValueChangeEvent, ReactiveDeterminationExecutionEvent, JsonLogicRecord, ComponentDocMeta, SettingsValueProvider as SettingsValueProvider$1, AiCapabilityCategory, AiCapabilityCatalog, AiValueKind, ComponentAuthoringManifest } from '@praxisui/core';
4
4
  import { FormGroup } from '@angular/forms';
5
+ import { PraxisDynamicForm } from '@praxisui/dynamic-form';
5
6
  import { ThemePalette } from '@angular/material/core';
6
7
  import { BaseAiAdapter, PatchResult, PraxisAssistantTurnViewState, PraxisAssistantShellLayout, PraxisAssistantShellLabels, PraxisAssistantSessionSnapshot, PraxisAssistantShellQuickReply, PraxisAssistantShellMessage, PraxisAssistantShellContextItem } from '@praxisui/ai';
7
8
  import { CdkDragDrop } from '@angular/cdk/drag-drop';
@@ -51,6 +52,10 @@ interface StepConfig {
51
52
  mode?: 'create' | 'edit' | 'view';
52
53
  config?: FormConfig;
53
54
  schemaSource?: 'resource' | 'filter';
55
+ /** Explicit discovery URL. The stepper never infers schema authority. */
56
+ schemaUrl?: string;
57
+ apiEndpointKey?: ApiEndpoint | string;
58
+ apiUrlEntry?: ApiUrlEntry | null;
54
59
  formId?: string;
55
60
  };
56
61
  /** Rich editorial content rendered before the step form. */
@@ -100,10 +105,13 @@ interface StepperMetadata {
100
105
  }
101
106
  declare class PraxisStepper implements OnInit, AfterViewInit, OnDestroy {
102
107
  stepLabelTpl?: TemplateRef<any>;
108
+ private materialStepper?;
103
109
  _config: _angular_core.WritableSignal<StepperMetadata | null>;
104
110
  private _selectedIndex;
105
111
  private _formGroups;
112
+ private _formComponents;
106
113
  private _formValidity;
114
+ private _formPending;
107
115
  private readonly hostElement;
108
116
  private readonly renderer;
109
117
  private appliedHeaderClasses;
@@ -154,6 +162,17 @@ declare class PraxisStepper implements OnInit, AfterViewInit, OnDestroy {
154
162
  stepId?: string;
155
163
  event: FormValueChangeEvent;
156
164
  }>;
165
+ /** Metadata-only determination lifecycle forwarded from the child form. */
166
+ stepReactiveDeterminationExecuted: EventEmitter<{
167
+ stepIndex: number;
168
+ stepId?: string;
169
+ event: ReactiveDeterminationExecutionEvent;
170
+ }>;
171
+ stepReactiveDeterminationPendingChange: EventEmitter<{
172
+ stepIndex: number;
173
+ stepId?: string;
174
+ pending: boolean;
175
+ }>;
157
176
  stepperContext?: Record<string, any>;
158
177
  private readonly settings;
159
178
  private readonly storage;
@@ -214,9 +233,12 @@ declare class PraxisStepper implements OnInit, AfterViewInit, OnDestroy {
214
233
  next(): void;
215
234
  prev(): void;
216
235
  reset(): void;
236
+ private advanceTo;
217
237
  previous(): void;
218
- onFormReady(stepIndex: number, ev: FormReadyEvent): void;
238
+ onFormReady(stepIndex: number, ev: FormReadyEvent, component?: PraxisDynamicForm): void;
219
239
  onFormValueChange(stepIndex: number, ev: FormValueChangeEvent): void;
240
+ onReactiveDeterminationExecuted(stepIndex: number, event: ReactiveDeterminationExecutionEvent): void;
241
+ onReactiveDeterminationPendingChange(stepIndex: number, pending: boolean): void;
220
242
  formGroupFor(i: number): FormGroup | undefined;
221
243
  computedCompleted(i: number, step: StepConfig): boolean;
222
244
  computedHasError(i: number, step: StepConfig): boolean;
@@ -272,7 +294,7 @@ declare class PraxisStepper implements OnInit, AfterViewInit, OnDestroy {
272
294
  private parseClassList;
273
295
  private resolveCssTokenName;
274
296
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<PraxisStepper, never>;
275
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<PraxisStepper, "praxis-stepper", never, { "stepperId": { "alias": "stepperId"; "required": true; }; "componentInstanceId": { "alias": "componentInstanceId"; "required": false; }; "config": { "alias": "config"; "required": false; }; "selectedIndexInput": { "alias": "selectedIndexInput"; "required": false; }; "selectedIndex": { "alias": "selectedIndex"; "required": false; }; "disableRippleInput": { "alias": "disableRippleInput"; "required": false; }; "enableCustomization": { "alias": "enableCustomization"; "required": false; }; "labelPosition": { "alias": "labelPosition"; "required": false; }; "color": { "alias": "color"; "required": false; }; "serverValidate": { "alias": "serverValidate"; "required": false; }; "stepperContext": { "alias": "stepperContext"; "required": false; }; }, { "selectedIndexChange": "selectedIndexChange"; "widgetEvent": "widgetEvent"; "stepFormReady": "stepFormReady"; "stepFormValueChange": "stepFormValueChange"; "animationDone": "animationDone"; "selectionChange": "selectionChange"; }, ["stepLabelTpl"], ["*"], true, never>;
297
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<PraxisStepper, "praxis-stepper", never, { "stepperId": { "alias": "stepperId"; "required": true; }; "componentInstanceId": { "alias": "componentInstanceId"; "required": false; }; "config": { "alias": "config"; "required": false; }; "selectedIndexInput": { "alias": "selectedIndexInput"; "required": false; }; "selectedIndex": { "alias": "selectedIndex"; "required": false; }; "disableRippleInput": { "alias": "disableRippleInput"; "required": false; }; "enableCustomization": { "alias": "enableCustomization"; "required": false; }; "labelPosition": { "alias": "labelPosition"; "required": false; }; "color": { "alias": "color"; "required": false; }; "serverValidate": { "alias": "serverValidate"; "required": false; }; "stepperContext": { "alias": "stepperContext"; "required": false; }; }, { "selectedIndexChange": "selectedIndexChange"; "widgetEvent": "widgetEvent"; "stepFormReady": "stepFormReady"; "stepFormValueChange": "stepFormValueChange"; "stepReactiveDeterminationExecuted": "stepReactiveDeterminationExecuted"; "stepReactiveDeterminationPendingChange": "stepReactiveDeterminationPendingChange"; "animationDone": "animationDone"; "selectionChange": "selectionChange"; }, ["stepLabelTpl"], ["*"], true, never>;
276
298
  }
277
299
 
278
300
  declare const PRAXIS_STEPPER_COMPONENT_METADATA: ComponentDocMeta;
@@ -460,6 +482,14 @@ interface WizardCtaConfig {
460
482
  interface WizardStepFormConfig {
461
483
  formId?: string;
462
484
  config: FormConfig;
485
+ resourcePath?: string;
486
+ resourceId?: string | number;
487
+ mode?: 'create' | 'edit' | 'view';
488
+ schemaSource?: 'resource' | 'filter';
489
+ /** Explicit schema authority; the wizard never derives it. */
490
+ schemaUrl?: string;
491
+ apiEndpointKey?: ApiEndpoint | string;
492
+ apiUrlEntry?: ApiUrlEntry | null;
463
493
  }
464
494
  interface WizardStepConfig {
465
495
  id: string;