@praxisui/stepper 9.0.5-rc.3 → 9.0.5-rc.31

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`, per-step pending state as `stepReactiveDeterminationPendingChange`, and component-level stability as `reactiveDeterminationStabilityChange`. The aggregate status is `pending`, `settled-satisfied`, or `settled-unsatisfied`; hosts must not interpret “settled” alone as success. Next and wizard submit remain blocked until the child form settles satisfied (or remain blocked after timeout/failure).
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-12T03:48:40.610Z",
3
+ "generatedAt": "2026-08-17T10:00:22.451Z",
4
4
  "packageName": "@praxisui/stepper",
5
- "packageVersion": "9.0.5-rc.3",
5
+ "packageVersion": "9.0.5-rc.31",
6
6
  "sourceRegistry": "praxis-component-registry-ingestion",
7
7
  "sourceRegistryVersion": "1.0.0",
8
8
  "componentCount": 1,
@@ -121,6 +121,24 @@
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"
136
+ },
137
+ {
138
+ "name": "reactiveDeterminationStabilityChange",
139
+ "type": "StepperReactiveDeterminationStabilityChange",
140
+ "required": false,
141
+ "label": "Estabilidade agregada: pending, settled-satisfied ou settled-unsatisfied"
124
142
  }
125
143
  ],
126
144
  "configSchemaId": null,
@@ -2128,9 +2146,9 @@
2128
2146
  {
2129
2147
  "chunkIndex": 0,
2130
2148
  "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",
2149
+ "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 - reactiveDeterminationStabilityChange (StepperReactiveDeterminationStabilityChange)\n",
2132
2150
  "sourcePointer": "projects/praxis-stepper/src/lib/praxis-stepper.metadata.ts",
2133
- "contentHash": "d753191bcc0a9e88df19ce2d3becb8dbc928e8c22db0d488dcfcdde2381c8e79",
2151
+ "contentHash": "45d94ab8764dc92a68f79332305178436a43403578fa626846dbc9f163684a37",
2134
2152
  "sourceKind": "component_definition",
2135
2153
  "sourceId": "praxis-stepper",
2136
2154
  "corpusVersion": "1.0.0"
@@ -1311,10 +1311,12 @@ class PraxisStepperConfigEditor {
1311
1311
  return;
1312
1312
  const apply = (val) => {
1313
1313
  const v = val || {};
1314
+ const existing = step.form;
1314
1315
  step.form = {
1315
- config: v.formConfig || v.config || step.form?.config || { sections: [] },
1316
- formId: v?.formId || step.form?.formId || step.id,
1317
- mode: v?.inputsPatch?.mode || v?.bindings?.mode || step.form?.mode || 'create',
1316
+ ...existing,
1317
+ config: v.formConfig || v.config || existing?.config || { sections: [] },
1318
+ formId: v?.formId || existing?.formId || step.id,
1319
+ mode: v?.inputsPatch?.mode || v?.bindings?.mode || existing?.mode || 'create',
1318
1320
  };
1319
1321
  this.markDirty();
1320
1322
  };
@@ -3414,18 +3416,21 @@ class StepperAgenticAuthoringTurnFlow {
3414
3416
  class PraxisStepper {
3415
3417
  // Templates projetados
3416
3418
  stepLabelTpl;
3419
+ materialStepper;
3417
3420
  // Dados e estado
3418
3421
  _config = signal(null, ...(ngDevMode ? [{ debugName: "_config" }] : /* istanbul ignore next */ []));
3419
3422
  _selectedIndex = signal(0, ...(ngDevMode ? [{ debugName: "_selectedIndex" }] : /* istanbul ignore next */ []));
3420
3423
  _formGroups = new Map();
3424
+ _formComponents = new Map();
3421
3425
  _formValidity = new Map();
3426
+ _formPending = new Map();
3422
3427
  hostElement = inject((ElementRef));
3423
3428
  renderer = inject(Renderer2);
3424
3429
  appliedHeaderClasses = [];
3425
3430
  appliedTokenNames = [];
3426
3431
  // CTA models for empty state
3427
- primaryCta = { label: 'Configurar Stepper', icon: 'tune', color: 'primary', action: () => this.openEditor() };
3428
- secondaryCtas = [{ label: 'Adicionar etapa inicial', icon: 'add', action: () => this.addFirstStep() }];
3432
+ primaryCta = { label: 'Configurar Stepper', icon: 'tune', color: 'primary', action: () => this.openEditor(), };
3433
+ secondaryCtas = [{ label: 'Adicionar etapa inicial', icon: 'add', action: () => this.addFirstStep(), },];
3429
3434
  // API de entrada
3430
3435
  stepperId;
3431
3436
  componentInstanceId;
@@ -3471,6 +3476,11 @@ class PraxisStepper {
3471
3476
  widgetEvent = new EventEmitter();
3472
3477
  stepFormReady = new EventEmitter();
3473
3478
  stepFormValueChange = new EventEmitter();
3479
+ /** Metadata-only determination lifecycle forwarded from the child form. */
3480
+ stepReactiveDeterminationExecuted = new EventEmitter();
3481
+ stepReactiveDeterminationPendingChange = new EventEmitter();
3482
+ /** Aggregate stability; settled-unsatisfied is intentionally distinct from success. */
3483
+ reactiveDeterminationStabilityChange = new EventEmitter();
3474
3484
  stepperContext;
3475
3485
  settings = inject(SettingsPanelService);
3476
3486
  storage = inject(ASYNC_CONFIG_STORAGE);
@@ -3483,6 +3493,7 @@ class PraxisStepper {
3483
3493
  return undefined;
3484
3494
  } })();
3485
3495
  cdr = inject(ChangeDetectorRef);
3496
+ reactiveDeterminationStabilitySignature = '';
3486
3497
  aiApi = inject(AiBackendApiService);
3487
3498
  assistantSessions = inject(PraxisAssistantSessionRegistryService);
3488
3499
  aiTurnOrchestrator = inject(PraxisAssistantTurnOrchestratorService);
@@ -3559,7 +3570,8 @@ class PraxisStepper {
3559
3570
  }
3560
3571
  };
3561
3572
  isNextDisabled(i) {
3562
- return this.linear() && this._formValidity.get(i) === false;
3573
+ return (this.hasBlockingReactiveDetermination(i) ||
3574
+ (this.linear() && this._formValidity.get(i) === false));
3563
3575
  }
3564
3576
  clampIndex(idx) {
3565
3577
  const len = this.steps().length;
@@ -3582,6 +3594,13 @@ class PraxisStepper {
3582
3594
  trackStep = (_, s) => s.id || _;
3583
3595
  onSelectionChange(ev) {
3584
3596
  const idx = this.clampIndex(ev?.selectedIndex ?? 0);
3597
+ const current = this._selectedIndex();
3598
+ if (idx !== current && this.hasBlockingReactiveDetermination(current)) {
3599
+ if (this.materialStepper)
3600
+ this.materialStepper.selectedIndex = current;
3601
+ this.cdr.markForCheck();
3602
+ return;
3603
+ }
3585
3604
  this._selectedIndex.set(idx);
3586
3605
  this.selectedIndexChange.emit(idx);
3587
3606
  this.selectionChange.emit(ev);
@@ -3589,14 +3608,18 @@ class PraxisStepper {
3589
3608
  // API programática básica
3590
3609
  goTo(index) {
3591
3610
  const clamped = this.clampIndex(index);
3592
- this._selectedIndex.set(clamped);
3593
- this.selectedIndexChange.emit(clamped);
3611
+ if (clamped !==
3612
+ this._selectedIndex() &&
3613
+ this.hasBlockingReactiveDetermination(this._selectedIndex())) {
3614
+ return;
3615
+ }
3616
+ this.advanceTo(clamped);
3594
3617
  }
3595
3618
  next() {
3596
3619
  const curr = this._selectedIndex();
3597
3620
  const len = this.steps().length;
3598
- if (curr < len - 1)
3599
- this.goTo(curr + 1);
3621
+ if (curr < len - 1 && !this.hasBlockingReactiveDetermination(curr))
3622
+ this.advanceTo(curr + 1);
3600
3623
  }
3601
3624
  prev() {
3602
3625
  const curr = this._selectedIndex();
@@ -3604,11 +3627,18 @@ class PraxisStepper {
3604
3627
  this.goTo(curr - 1);
3605
3628
  }
3606
3629
  reset() { this.goTo(0); }
3630
+ advanceTo(index) {
3631
+ const clamped = this.clampIndex(index);
3632
+ this._selectedIndex.set(clamped);
3633
+ this.selectedIndexChange.emit(clamped);
3634
+ }
3607
3635
  // Alias para compatibilidade nominal com MatStepper
3608
3636
  previous() { this.prev(); }
3609
3637
  // Dynamic Form integration
3610
- onFormReady(stepIndex, ev) {
3638
+ onFormReady(stepIndex, ev, component) {
3611
3639
  this._formGroups.set(stepIndex, ev.formGroup);
3640
+ if (component)
3641
+ this._formComponents.set(stepIndex, component);
3612
3642
  this._formValidity.set(stepIndex, ev.formGroup.valid);
3613
3643
  this.stepFormReady.emit({
3614
3644
  stepIndex,
@@ -3624,6 +3654,40 @@ class PraxisStepper {
3624
3654
  event: ev,
3625
3655
  });
3626
3656
  }
3657
+ onReactiveDeterminationExecuted(stepIndex, event) {
3658
+ this.stepReactiveDeterminationExecuted.emit({
3659
+ stepIndex,
3660
+ stepId: this.steps()[stepIndex]?.id,
3661
+ event,
3662
+ });
3663
+ this.emitReactiveDeterminationStability();
3664
+ }
3665
+ onReactiveDeterminationPendingChange(stepIndex, pending) {
3666
+ this._formPending.set(stepIndex, pending);
3667
+ this.stepReactiveDeterminationPendingChange.emit({
3668
+ stepIndex,
3669
+ stepId: this.steps()[stepIndex]?.id,
3670
+ pending,
3671
+ });
3672
+ this.emitReactiveDeterminationStability();
3673
+ this.cdr.markForCheck();
3674
+ }
3675
+ emitReactiveDeterminationStability() {
3676
+ const stepIndexes = this.steps().map((_, index) => index);
3677
+ const pending = stepIndexes.some((index) => this._formPending.get(index) === true ||
3678
+ this._formComponents.get(index)?.hasPendingReactiveDeterminations?.() === true);
3679
+ const unsatisfied = stepIndexes.some((index) => this._formComponents.get(index)?.hasUnsatisfiedReactiveDeterminations?.() === true);
3680
+ const status = pending
3681
+ ? 'pending'
3682
+ : unsatisfied
3683
+ ? 'settled-unsatisfied'
3684
+ : 'settled-satisfied';
3685
+ const signature = `${status}:${pending}:${unsatisfied}`;
3686
+ if (signature === this.reactiveDeterminationStabilitySignature)
3687
+ return;
3688
+ this.reactiveDeterminationStabilitySignature = signature;
3689
+ this.reactiveDeterminationStabilityChange.emit({ status, pending, unsatisfied });
3690
+ }
3627
3691
  formGroupFor(i) {
3628
3692
  return this._formGroups.get(i);
3629
3693
  }
@@ -3672,12 +3736,12 @@ class PraxisStepper {
3672
3736
  };
3673
3737
  }
3674
3738
  openEditor() {
3675
- const cfg = this._config() || { steps: [], orientation: 'horizontal', headerPosition: 'top', linear: false };
3739
+ const cfg = this._config() || { steps: [], orientation: 'horizontal', headerPosition: 'top', linear: false, };
3676
3740
  const key = this.storageKey() || this.stepperId || 'default';
3677
3741
  const ref = this.settings.open({
3678
3742
  id: `praxis-stepper-editor:${key}`,
3679
3743
  title: 'Configurar Stepper',
3680
- content: { component: PraxisStepperConfigEditor, inputs: { config: cfg } },
3744
+ content: { component: PraxisStepperConfigEditor, inputs: { config: cfg }, },
3681
3745
  });
3682
3746
  const apply = (value) => {
3683
3747
  const nextCfg = value?.config || value;
@@ -3900,7 +3964,7 @@ class PraxisStepper {
3900
3964
  'steps',
3901
3965
  'selectedIndex',
3902
3966
  'linear',
3903
- 'orientation',
3967
+ 'orientation'
3904
3968
  ],
3905
3969
  },
3906
3970
  capabilityRefs: [
@@ -3938,18 +4002,18 @@ class PraxisStepper {
3938
4002
  });
3939
4003
  }
3940
4004
  hasAiAssistantSessionState() {
3941
- return !!this.aiAssistantPrompt.trim()
4005
+ return (!!this.aiAssistantPrompt.trim()
3942
4006
  || !!this.aiAssistantViewState?.messages?.length
3943
4007
  || !!this.aiAssistantViewState?.quickReplies?.length
3944
4008
  || !!this.aiAssistantViewState?.pendingPatch
3945
4009
  || !!this.aiAssistantViewState?.statusText?.trim()
3946
- || !!this.aiAssistantViewState?.errorText?.trim();
4010
+ || !!this.aiAssistantViewState?.errorText?.trim());
3947
4011
  }
3948
4012
  resolveAiAssistantSessionId() {
3949
4013
  return `stepper:${this.resolveAiAssistantRouteKey()}:${this.resolveAiAssistantOwnerId()}`;
3950
4014
  }
3951
4015
  resolveAiAssistantOwnerId() {
3952
- return (this.componentInstanceId || this.safeAiAssistantStepperId() || 'stepper').trim() || 'stepper';
4016
+ return ((this.componentInstanceId || this.safeAiAssistantStepperId() || 'stepper').trim() || 'stepper');
3953
4017
  }
3954
4018
  safeAiAssistantStepperId() {
3955
4019
  return String(this.stepperId || '').trim();
@@ -4008,19 +4072,19 @@ class PraxisStepper {
4008
4072
  stepCount: steps.length,
4009
4073
  formStepCount: steps.filter((step) => !!step.form).length,
4010
4074
  widgetStepCount: steps.filter((step) => Array.isArray(step.widgets) && step.widgets.length > 0).length,
4011
- richContentStepCount: steps.filter((step) => (this.hasRichContent(step.stepBlocksBeforeForm)
4012
- || this.hasRichContent(step.stepBlocksAfterForm))).length,
4075
+ richContentStepCount: steps.filter((step) => this.hasRichContent(step.stepBlocksBeforeForm)
4076
+ || this.hasRichContent(step.stepBlocksAfterForm)).length,
4013
4077
  };
4014
4078
  }
4015
4079
  // CTA helpers
4016
4080
  addFirstStep() {
4017
- const current = this._config() || { steps: [], orientation: 'horizontal', headerPosition: 'top', linear: false };
4081
+ const current = this._config() || { steps: [], orientation: 'horizontal', headerPosition: 'top', linear: false, };
4018
4082
  if ((current.steps || []).length > 0)
4019
4083
  return;
4020
4084
  const next = {
4021
4085
  ...current,
4022
4086
  steps: [
4023
- { id: 'step1', label: 'Etapa 1', description: 'Clique em Configurar para editar esta etapa.' },
4087
+ { id: 'step1', label: 'Etapa 1', description: 'Clique em Configurar para editar esta etapa.', },
4024
4088
  ],
4025
4089
  };
4026
4090
  this._config.set(next);
@@ -4034,6 +4098,12 @@ class PraxisStepper {
4034
4098
  await this.nextWithValidation(i);
4035
4099
  }
4036
4100
  async validateStep(i = this.selectedIndexComputed()) {
4101
+ const childForm = this._formComponents.get(i);
4102
+ if (childForm && this.hasBlockingReactiveDetermination(i)) {
4103
+ const stable = await childForm.waitForReactiveDeterminations();
4104
+ if (!stable)
4105
+ return false;
4106
+ }
4037
4107
  // Em modo linear, bloquear quando inválido
4038
4108
  if (this.linear() && this._formValidity.get(i) === false) {
4039
4109
  const fg = this._formGroups.get(i);
@@ -4050,7 +4120,7 @@ class PraxisStepper {
4050
4120
  const fg = this._formGroups.get(i);
4051
4121
  const data = fg?.getRawValue();
4052
4122
  if (this.serverValidate) {
4053
- const res = await this.serverValidate({ step, stepIndex: i, formGroup: fg, formData: data });
4123
+ const res = await this.serverValidate({ step, stepIndex: i, formGroup: fg, formData: data, });
4054
4124
  if (!res.ok) {
4055
4125
  this.applyServerErrors(fg, res.fieldErrors, res.formErrors);
4056
4126
  // Atualizar erro visual
@@ -4058,6 +4128,11 @@ class PraxisStepper {
4058
4128
  this._formValidity.set(i, false);
4059
4129
  return false;
4060
4130
  }
4131
+ if (childForm && this.hasBlockingReactiveDetermination(i)) {
4132
+ const stable = await childForm.waitForReactiveDeterminations();
4133
+ if (!stable)
4134
+ return false;
4135
+ }
4061
4136
  }
4062
4137
  return true;
4063
4138
  }
@@ -4066,9 +4141,18 @@ class PraxisStepper {
4066
4141
  if (!isValid) {
4067
4142
  return false;
4068
4143
  }
4069
- this.next();
4144
+ const current = this._selectedIndex();
4145
+ if (current < this.steps().length - 1)
4146
+ this.advanceTo(current + 1);
4070
4147
  return true;
4071
4148
  }
4149
+ hasBlockingReactiveDetermination(stepIndex) {
4150
+ if (this._formPending.get(stepIndex) === true)
4151
+ return true;
4152
+ const childForm = this._formComponents.get(stepIndex);
4153
+ return (childForm?.hasPendingReactiveDeterminations?.() === true ||
4154
+ childForm?.hasUnsatisfiedReactiveDeterminations?.() === true);
4155
+ }
4072
4156
  onPrev() { this.prev(); }
4073
4157
  onAnimationDone() { this.animationDone.emit(); }
4074
4158
  applyServerErrors(fg, fieldErrors, formErrors) {
@@ -4190,7 +4274,7 @@ class PraxisStepper {
4190
4274
  return name.startsWith('--') ? name : `--${name}`;
4191
4275
  }
4192
4276
  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: `
4277
+ 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", reactiveDeterminationStabilityChange: "reactiveDeterminationStabilityChange", 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
4278
  @if (enableCustomization) {
4195
4279
  <div class="stepper-ai-assistant">
4196
4280
  <button
@@ -4217,7 +4301,10 @@ class PraxisStepper {
4217
4301
  [prompt]="aiAssistantPrompt"
4218
4302
  [statusText]="aiAssistantViewState.statusText"
4219
4303
  [errorText]="aiAssistantViewState.errorText"
4220
- [busy]="aiAssistantViewState.state === 'processing' || aiAssistantViewState.state === 'applying'"
4304
+ [busy]="
4305
+ aiAssistantViewState.state === 'processing' ||
4306
+ aiAssistantViewState.state === 'applying'
4307
+ "
4221
4308
  [canApply]="aiAssistantViewState.canApply"
4222
4309
  [labels]="aiAssistantLabels"
4223
4310
  [layout]="aiAssistantLayout"
@@ -4299,26 +4386,40 @@ class PraxisStepper {
4299
4386
  <div [class]="contentClassList()">
4300
4387
  @if (hasRichContent(step.stepBlocksBeforeForm)) {
4301
4388
  <praxis-rich-content
4302
- [document]="step.stepBlocksBeforeForm || emptyStepRichContentDocument"
4389
+ [document]="
4390
+ step.stepBlocksBeforeForm || emptyStepRichContentDocument
4391
+ "
4303
4392
  [context]="getStepRichContentContext(i)"
4304
4393
  rootClassName="pdx-step-rich-content pdx-step-rich-content--before"
4305
4394
  ></praxis-rich-content>
4306
4395
  }
4307
4396
  @if (step.form; as f) {
4308
4397
  <praxis-dynamic-form
4398
+ #stepForm
4309
4399
  [resourcePath]="f.resourcePath"
4310
4400
  [resourceId]="$any(f.resourceId)"
4311
4401
  [mode]="f.mode || 'create'"
4312
4402
  [config]="f.config || { sections: [] }"
4313
4403
  [schemaSource]="f.schemaSource || 'resource'"
4404
+ [schemaUrl]="f.schemaUrl"
4405
+ [apiEndpointKey]="$any(f.apiEndpointKey)"
4406
+ [apiUrlEntry]="f.apiUrlEntry || null"
4314
4407
  [formId]="f.formId"
4315
- (formReady)="onFormReady(i, $event)"
4408
+ (formReady)="onFormReady(i, $event, stepForm)"
4316
4409
  (valueChange)="onFormValueChange(i, $event)"
4410
+ (reactiveDeterminationExecuted)="
4411
+ onReactiveDeterminationExecuted(i, $event)
4412
+ "
4413
+ (reactiveDeterminationPendingChange)="
4414
+ onReactiveDeterminationPendingChange(i, $event)
4415
+ "
4317
4416
  ></praxis-dynamic-form>
4318
4417
  }
4319
4418
  @if (hasRichContent(step.stepBlocksAfterForm)) {
4320
4419
  <praxis-rich-content
4321
- [document]="step.stepBlocksAfterForm || emptyStepRichContentDocument"
4420
+ [document]="
4421
+ step.stepBlocksAfterForm || emptyStepRichContentDocument
4422
+ "
4322
4423
  [context]="getStepRichContentContext(i)"
4323
4424
  rootClassName="pdx-step-rich-content pdx-step-rich-content--after"
4324
4425
  ></praxis-rich-content>
@@ -4329,7 +4430,8 @@ class PraxisStepper {
4329
4430
  [context]="stepperContext"
4330
4431
  [strictValidation]="true"
4331
4432
  [autoWireOutputs]="true"
4332
- (widgetEvent)="onChildWidgetEvent(i, wd, $event)"></ng-container>
4433
+ (widgetEvent)="onChildWidgetEvent(i, wd, $event)"
4434
+ ></ng-container>
4333
4435
  }
4334
4436
  @if (isStepEmpty(step)) {
4335
4437
  <praxis-empty-state-card
@@ -4337,7 +4439,11 @@ class PraxisStepper {
4337
4439
  icon="dashboard_customize"
4338
4440
  title="Sem conteúdo nesta etapa"
4339
4441
  description="Adicione um formulário ou widgets a esta etapa, ou abra o editor para configurar."
4340
- [primaryAction]="{ label: 'Abrir editor', icon: 'tune', action: openEditor.bind(this) }"
4442
+ [primaryAction]="{
4443
+ label: 'Abrir editor',
4444
+ icon: 'tune',
4445
+ action: openEditor.bind(this),
4446
+ }"
4341
4447
  ></praxis-empty-state-card>
4342
4448
  }
4343
4449
  </div>
@@ -4347,7 +4453,12 @@ class PraxisStepper {
4347
4453
  @if (selectedIndexComputed() > 0) {
4348
4454
  @switch (navVariant()) {
4349
4455
  @case ('flat') {
4350
- <button mat-flat-button [color]="navColor()" type="button" (click)="onPrev()">
4456
+ <button
4457
+ mat-flat-button
4458
+ [color]="navColor()"
4459
+ type="button"
4460
+ (click)="onPrev()"
4461
+ >
4351
4462
  @if (navPrevIcon(); as ic) {
4352
4463
  <mat-icon [praxisIcon]="ic"></mat-icon>
4353
4464
  }
@@ -4355,7 +4466,12 @@ class PraxisStepper {
4355
4466
  </button>
4356
4467
  }
4357
4468
  @case ('stroked') {
4358
- <button mat-stroked-button [color]="navColor()" type="button" (click)="onPrev()">
4469
+ <button
4470
+ mat-stroked-button
4471
+ [color]="navColor()"
4472
+ type="button"
4473
+ (click)="onPrev()"
4474
+ >
4359
4475
  @if (navPrevIcon(); as ic) {
4360
4476
  <mat-icon [praxisIcon]="ic"></mat-icon>
4361
4477
  }
@@ -4363,7 +4479,12 @@ class PraxisStepper {
4363
4479
  </button>
4364
4480
  }
4365
4481
  @case ('raised') {
4366
- <button mat-raised-button [color]="navColor()" type="button" (click)="onPrev()">
4482
+ <button
4483
+ mat-raised-button
4484
+ [color]="navColor()"
4485
+ type="button"
4486
+ (click)="onPrev()"
4487
+ >
4367
4488
  @if (navPrevIcon(); as ic) {
4368
4489
  <mat-icon [praxisIcon]="ic"></mat-icon>
4369
4490
  }
@@ -4371,7 +4492,12 @@ class PraxisStepper {
4371
4492
  </button>
4372
4493
  }
4373
4494
  @default {
4374
- <button mat-button [color]="navColor()" type="button" (click)="onPrev()">
4495
+ <button
4496
+ mat-button
4497
+ [color]="navColor()"
4498
+ type="button"
4499
+ (click)="onPrev()"
4500
+ >
4375
4501
  @if (navPrevIcon(); as ic) {
4376
4502
  <mat-icon [praxisIcon]="ic"></mat-icon>
4377
4503
  }
@@ -4383,7 +4509,13 @@ class PraxisStepper {
4383
4509
  <!-- NEXT button -->
4384
4510
  @switch (navVariant()) {
4385
4511
  @case ('flat') {
4386
- <button mat-flat-button [color]="navColor()" type="button" (click)="onNext(i)" [disabled]="isNextDisabled(i)">
4512
+ <button
4513
+ mat-flat-button
4514
+ [color]="navColor()"
4515
+ type="button"
4516
+ (click)="onNext(i)"
4517
+ [disabled]="isNextDisabled(i)"
4518
+ >
4387
4519
  {{ navNextLabel() }}
4388
4520
  @if (navNextIcon(); as ic) {
4389
4521
  <mat-icon [praxisIcon]="ic"></mat-icon>
@@ -4391,7 +4523,13 @@ class PraxisStepper {
4391
4523
  </button>
4392
4524
  }
4393
4525
  @case ('stroked') {
4394
- <button mat-stroked-button [color]="navColor()" type="button" (click)="onNext(i)" [disabled]="isNextDisabled(i)">
4526
+ <button
4527
+ mat-stroked-button
4528
+ [color]="navColor()"
4529
+ type="button"
4530
+ (click)="onNext(i)"
4531
+ [disabled]="isNextDisabled(i)"
4532
+ >
4395
4533
  {{ navNextLabel() }}
4396
4534
  @if (navNextIcon(); as ic) {
4397
4535
  <mat-icon [praxisIcon]="ic"></mat-icon>
@@ -4399,7 +4537,13 @@ class PraxisStepper {
4399
4537
  </button>
4400
4538
  }
4401
4539
  @case ('raised') {
4402
- <button mat-raised-button [color]="navColor()" type="button" (click)="onNext(i)" [disabled]="isNextDisabled(i)">
4540
+ <button
4541
+ mat-raised-button
4542
+ [color]="navColor()"
4543
+ type="button"
4544
+ (click)="onNext(i)"
4545
+ [disabled]="isNextDisabled(i)"
4546
+ >
4403
4547
  {{ navNextLabel() }}
4404
4548
  @if (navNextIcon(); as ic) {
4405
4549
  <mat-icon [praxisIcon]="ic"></mat-icon>
@@ -4407,7 +4551,13 @@ class PraxisStepper {
4407
4551
  </button>
4408
4552
  }
4409
4553
  @default {
4410
- <button mat-button [color]="navColor()" type="button" (click)="onNext(i)" [disabled]="isNextDisabled(i)">
4554
+ <button
4555
+ mat-button
4556
+ [color]="navColor()"
4557
+ type="button"
4558
+ (click)="onNext(i)"
4559
+ [disabled]="isNextDisabled(i)"
4560
+ >
4411
4561
  {{ navNextLabel() }}
4412
4562
  @if (navNextIcon(); as ic) {
4413
4563
  <mat-icon [praxisIcon]="ic"></mat-icon>
@@ -4440,12 +4590,12 @@ class PraxisStepper {
4440
4590
  <mat-icon fontIcon="edit"></mat-icon>
4441
4591
  </button>
4442
4592
  }
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"] }, { 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 });
4593
+ `, 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", "submitResourceVersionTargetResourceKey", "submitResourceVersionTargetIdField", "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
4594
  }
4445
4595
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisStepper, decorators: [{
4446
4596
  type: Component,
4447
- args: [{ selector: 'praxis-stepper', standalone: true, imports: [CommonModule, ReactiveFormsModule, MatStepperModule, MatButtonModule, MatIconModule, PraxisIconDirective, PraxisDynamicForm, DynamicWidgetLoaderDirective, EmptyStateCardComponent, PraxisAiAssistantShellComponent, PraxisRichContent], host: {
4448
- '[class]': 'densityClass()'
4597
+ args: [{ selector: 'praxis-stepper', standalone: true, imports: [CommonModule, ReactiveFormsModule, MatStepperModule, MatButtonModule, MatIconModule, PraxisIconDirective, PraxisDynamicForm, DynamicWidgetLoaderDirective, EmptyStateCardComponent, PraxisAiAssistantShellComponent, PraxisRichContent,], host: {
4598
+ '[class]': 'densityClass()',
4449
4599
  }, template: `
4450
4600
  @if (enableCustomization) {
4451
4601
  <div class="stepper-ai-assistant">
@@ -4473,7 +4623,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
4473
4623
  [prompt]="aiAssistantPrompt"
4474
4624
  [statusText]="aiAssistantViewState.statusText"
4475
4625
  [errorText]="aiAssistantViewState.errorText"
4476
- [busy]="aiAssistantViewState.state === 'processing' || aiAssistantViewState.state === 'applying'"
4626
+ [busy]="
4627
+ aiAssistantViewState.state === 'processing' ||
4628
+ aiAssistantViewState.state === 'applying'
4629
+ "
4477
4630
  [canApply]="aiAssistantViewState.canApply"
4478
4631
  [labels]="aiAssistantLabels"
4479
4632
  [layout]="aiAssistantLayout"
@@ -4555,26 +4708,40 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
4555
4708
  <div [class]="contentClassList()">
4556
4709
  @if (hasRichContent(step.stepBlocksBeforeForm)) {
4557
4710
  <praxis-rich-content
4558
- [document]="step.stepBlocksBeforeForm || emptyStepRichContentDocument"
4711
+ [document]="
4712
+ step.stepBlocksBeforeForm || emptyStepRichContentDocument
4713
+ "
4559
4714
  [context]="getStepRichContentContext(i)"
4560
4715
  rootClassName="pdx-step-rich-content pdx-step-rich-content--before"
4561
4716
  ></praxis-rich-content>
4562
4717
  }
4563
4718
  @if (step.form; as f) {
4564
4719
  <praxis-dynamic-form
4720
+ #stepForm
4565
4721
  [resourcePath]="f.resourcePath"
4566
4722
  [resourceId]="$any(f.resourceId)"
4567
4723
  [mode]="f.mode || 'create'"
4568
4724
  [config]="f.config || { sections: [] }"
4569
4725
  [schemaSource]="f.schemaSource || 'resource'"
4726
+ [schemaUrl]="f.schemaUrl"
4727
+ [apiEndpointKey]="$any(f.apiEndpointKey)"
4728
+ [apiUrlEntry]="f.apiUrlEntry || null"
4570
4729
  [formId]="f.formId"
4571
- (formReady)="onFormReady(i, $event)"
4730
+ (formReady)="onFormReady(i, $event, stepForm)"
4572
4731
  (valueChange)="onFormValueChange(i, $event)"
4732
+ (reactiveDeterminationExecuted)="
4733
+ onReactiveDeterminationExecuted(i, $event)
4734
+ "
4735
+ (reactiveDeterminationPendingChange)="
4736
+ onReactiveDeterminationPendingChange(i, $event)
4737
+ "
4573
4738
  ></praxis-dynamic-form>
4574
4739
  }
4575
4740
  @if (hasRichContent(step.stepBlocksAfterForm)) {
4576
4741
  <praxis-rich-content
4577
- [document]="step.stepBlocksAfterForm || emptyStepRichContentDocument"
4742
+ [document]="
4743
+ step.stepBlocksAfterForm || emptyStepRichContentDocument
4744
+ "
4578
4745
  [context]="getStepRichContentContext(i)"
4579
4746
  rootClassName="pdx-step-rich-content pdx-step-rich-content--after"
4580
4747
  ></praxis-rich-content>
@@ -4585,7 +4752,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
4585
4752
  [context]="stepperContext"
4586
4753
  [strictValidation]="true"
4587
4754
  [autoWireOutputs]="true"
4588
- (widgetEvent)="onChildWidgetEvent(i, wd, $event)"></ng-container>
4755
+ (widgetEvent)="onChildWidgetEvent(i, wd, $event)"
4756
+ ></ng-container>
4589
4757
  }
4590
4758
  @if (isStepEmpty(step)) {
4591
4759
  <praxis-empty-state-card
@@ -4593,7 +4761,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
4593
4761
  icon="dashboard_customize"
4594
4762
  title="Sem conteúdo nesta etapa"
4595
4763
  description="Adicione um formulário ou widgets a esta etapa, ou abra o editor para configurar."
4596
- [primaryAction]="{ label: 'Abrir editor', icon: 'tune', action: openEditor.bind(this) }"
4764
+ [primaryAction]="{
4765
+ label: 'Abrir editor',
4766
+ icon: 'tune',
4767
+ action: openEditor.bind(this),
4768
+ }"
4597
4769
  ></praxis-empty-state-card>
4598
4770
  }
4599
4771
  </div>
@@ -4603,7 +4775,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
4603
4775
  @if (selectedIndexComputed() > 0) {
4604
4776
  @switch (navVariant()) {
4605
4777
  @case ('flat') {
4606
- <button mat-flat-button [color]="navColor()" type="button" (click)="onPrev()">
4778
+ <button
4779
+ mat-flat-button
4780
+ [color]="navColor()"
4781
+ type="button"
4782
+ (click)="onPrev()"
4783
+ >
4607
4784
  @if (navPrevIcon(); as ic) {
4608
4785
  <mat-icon [praxisIcon]="ic"></mat-icon>
4609
4786
  }
@@ -4611,7 +4788,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
4611
4788
  </button>
4612
4789
  }
4613
4790
  @case ('stroked') {
4614
- <button mat-stroked-button [color]="navColor()" type="button" (click)="onPrev()">
4791
+ <button
4792
+ mat-stroked-button
4793
+ [color]="navColor()"
4794
+ type="button"
4795
+ (click)="onPrev()"
4796
+ >
4615
4797
  @if (navPrevIcon(); as ic) {
4616
4798
  <mat-icon [praxisIcon]="ic"></mat-icon>
4617
4799
  }
@@ -4619,7 +4801,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
4619
4801
  </button>
4620
4802
  }
4621
4803
  @case ('raised') {
4622
- <button mat-raised-button [color]="navColor()" type="button" (click)="onPrev()">
4804
+ <button
4805
+ mat-raised-button
4806
+ [color]="navColor()"
4807
+ type="button"
4808
+ (click)="onPrev()"
4809
+ >
4623
4810
  @if (navPrevIcon(); as ic) {
4624
4811
  <mat-icon [praxisIcon]="ic"></mat-icon>
4625
4812
  }
@@ -4627,7 +4814,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
4627
4814
  </button>
4628
4815
  }
4629
4816
  @default {
4630
- <button mat-button [color]="navColor()" type="button" (click)="onPrev()">
4817
+ <button
4818
+ mat-button
4819
+ [color]="navColor()"
4820
+ type="button"
4821
+ (click)="onPrev()"
4822
+ >
4631
4823
  @if (navPrevIcon(); as ic) {
4632
4824
  <mat-icon [praxisIcon]="ic"></mat-icon>
4633
4825
  }
@@ -4639,7 +4831,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
4639
4831
  <!-- NEXT button -->
4640
4832
  @switch (navVariant()) {
4641
4833
  @case ('flat') {
4642
- <button mat-flat-button [color]="navColor()" type="button" (click)="onNext(i)" [disabled]="isNextDisabled(i)">
4834
+ <button
4835
+ mat-flat-button
4836
+ [color]="navColor()"
4837
+ type="button"
4838
+ (click)="onNext(i)"
4839
+ [disabled]="isNextDisabled(i)"
4840
+ >
4643
4841
  {{ navNextLabel() }}
4644
4842
  @if (navNextIcon(); as ic) {
4645
4843
  <mat-icon [praxisIcon]="ic"></mat-icon>
@@ -4647,7 +4845,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
4647
4845
  </button>
4648
4846
  }
4649
4847
  @case ('stroked') {
4650
- <button mat-stroked-button [color]="navColor()" type="button" (click)="onNext(i)" [disabled]="isNextDisabled(i)">
4848
+ <button
4849
+ mat-stroked-button
4850
+ [color]="navColor()"
4851
+ type="button"
4852
+ (click)="onNext(i)"
4853
+ [disabled]="isNextDisabled(i)"
4854
+ >
4651
4855
  {{ navNextLabel() }}
4652
4856
  @if (navNextIcon(); as ic) {
4653
4857
  <mat-icon [praxisIcon]="ic"></mat-icon>
@@ -4655,7 +4859,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
4655
4859
  </button>
4656
4860
  }
4657
4861
  @case ('raised') {
4658
- <button mat-raised-button [color]="navColor()" type="button" (click)="onNext(i)" [disabled]="isNextDisabled(i)">
4862
+ <button
4863
+ mat-raised-button
4864
+ [color]="navColor()"
4865
+ type="button"
4866
+ (click)="onNext(i)"
4867
+ [disabled]="isNextDisabled(i)"
4868
+ >
4659
4869
  {{ navNextLabel() }}
4660
4870
  @if (navNextIcon(); as ic) {
4661
4871
  <mat-icon [praxisIcon]="ic"></mat-icon>
@@ -4663,7 +4873,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
4663
4873
  </button>
4664
4874
  }
4665
4875
  @default {
4666
- <button mat-button [color]="navColor()" type="button" (click)="onNext(i)" [disabled]="isNextDisabled(i)">
4876
+ <button
4877
+ mat-button
4878
+ [color]="navColor()"
4879
+ type="button"
4880
+ (click)="onNext(i)"
4881
+ [disabled]="isNextDisabled(i)"
4882
+ >
4667
4883
  {{ navNextLabel() }}
4668
4884
  @if (navNextIcon(); as ic) {
4669
4885
  <mat-icon [praxisIcon]="ic"></mat-icon>
@@ -4696,10 +4912,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
4696
4912
  <mat-icon fontIcon="edit"></mat-icon>
4697
4913
  </button>
4698
4914
  }
4699
- `, 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"] }]
4915
+ `, 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"] }]
4700
4916
  }], propDecorators: { stepLabelTpl: [{
4701
4917
  type: ContentChild,
4702
4918
  args: ['stepLabelTpl', { read: TemplateRef }]
4919
+ }], materialStepper: [{
4920
+ type: ViewChild,
4921
+ args: ['stepperRoot']
4703
4922
  }], stepperId: [{
4704
4923
  type: Input,
4705
4924
  args: [{ required: true }]
@@ -4729,6 +4948,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
4729
4948
  type: Output
4730
4949
  }], stepFormValueChange: [{
4731
4950
  type: Output
4951
+ }], stepReactiveDeterminationExecuted: [{
4952
+ type: Output
4953
+ }], stepReactiveDeterminationPendingChange: [{
4954
+ type: Output
4955
+ }], reactiveDeterminationStabilityChange: [{
4956
+ type: Output
4732
4957
  }], stepperContext: [{
4733
4958
  type: Input
4734
4959
  }], animationDone: [{
@@ -5045,6 +5270,9 @@ const PRAXIS_STEPPER_COMPONENT_METADATA = {
5045
5270
  { name: 'widgetEvent', type: 'WidgetEventEnvelope', label: 'Evento interno' },
5046
5271
  { name: 'stepFormReady', type: '{ stepId?: string; stepIndex: number; event: FormReadyEvent }', label: 'Form ready (por etapa)' },
5047
5272
  { name: 'stepFormValueChange', type: '{ stepId?: string; stepIndex: number; event: FormValueChangeEvent }', label: 'Form value change (por etapa)' },
5273
+ { name: 'stepReactiveDeterminationExecuted', type: '{ stepId?: string; stepIndex: number; event: ReactiveDeterminationExecutionEvent }', label: 'Evidencia metadata-only por etapa' },
5274
+ { name: 'stepReactiveDeterminationPendingChange', type: '{ stepId?: string; stepIndex: number; pending: boolean }', label: 'Estado de estabilizacao por etapa' },
5275
+ { name: 'reactiveDeterminationStabilityChange', type: 'StepperReactiveDeterminationStabilityChange', label: 'Estabilidade agregada: pending, settled-satisfied ou settled-unsatisfied' },
5048
5276
  ],
5049
5277
  actions: [
5050
5278
  {
@@ -5492,7 +5720,13 @@ function buildStep(step, wizardId) {
5492
5720
  ? {
5493
5721
  formId: step.form.formId || `${wizardId}:${step.id}`,
5494
5722
  config: step.form.config,
5495
- mode: 'create',
5723
+ resourcePath: step.form.resourcePath,
5724
+ resourceId: step.form.resourceId,
5725
+ mode: step.form.mode || 'create',
5726
+ schemaSource: step.form.schemaSource,
5727
+ schemaUrl: step.form.schemaUrl,
5728
+ apiEndpointKey: step.form.apiEndpointKey,
5729
+ apiUrlEntry: step.form.apiUrlEntry,
5496
5730
  }
5497
5731
  : undefined,
5498
5732
  };
@@ -5974,7 +6208,7 @@ class PraxisWizardFormComponent {
5974
6208
  ></praxis-wizard-cta-bar>
5975
6209
  </mat-card>
5976
6210
  </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 });
6211
+ `, 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", "reactiveDeterminationStabilityChange", "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
6212
  }
5979
6213
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisWizardFormComponent, decorators: [{
5980
6214
  type: Component,
package/package.json CHANGED
@@ -1,22 +1,22 @@
1
1
  {
2
2
  "name": "@praxisui/stepper",
3
- "version": "9.0.5-rc.3",
3
+ "version": "9.0.5-rc.31",
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.3",
11
- "@praxisui/dynamic-form": "^9.0.5-rc.3",
12
- "@praxisui/rich-content": "^9.0.5-rc.3",
13
- "@praxisui/settings-panel": "^9.0.5-rc.3",
14
- "@praxisui/list": "^9.0.5-rc.3",
15
- "@praxisui/files-upload": "^9.0.5-rc.3",
16
- "@praxisui/page-builder": "^9.0.5-rc.3",
10
+ "@praxisui/core": "^9.0.5-rc.31",
11
+ "@praxisui/dynamic-form": "^9.0.5-rc.31",
12
+ "@praxisui/rich-content": "^9.0.5-rc.31",
13
+ "@praxisui/settings-panel": "^9.0.5-rc.31",
14
+ "@praxisui/list": "^9.0.5-rc.31",
15
+ "@praxisui/files-upload": "^9.0.5-rc.31",
16
+ "@praxisui/page-builder": "^9.0.5-rc.31",
17
17
  "@angular/forms": "^21.0.0",
18
18
  "@angular/router": "^21.0.0",
19
- "@praxisui/ai": "^9.0.5-rc.3",
19
+ "@praxisui/ai": "^9.0.5-rc.31",
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';
@@ -33,6 +34,13 @@ declare class StepperAiAdapter extends BaseAiAdapter<StepperMetadata> {
33
34
 
34
35
  type StepOrientation = 'horizontal' | 'vertical';
35
36
  type StepHeaderPosition = 'top' | 'bottom';
37
+ type StepperReactiveDeterminationStabilityStatus = 'pending' | 'settled-satisfied' | 'settled-unsatisfied';
38
+ /** Aggregate, value-free stability evidence for all Dynamic Forms owned by this stepper. */
39
+ interface StepperReactiveDeterminationStabilityChange {
40
+ status: StepperReactiveDeterminationStabilityStatus;
41
+ pending: boolean;
42
+ unsatisfied: boolean;
43
+ }
36
44
  interface StepConfig {
37
45
  id?: string;
38
46
  label: string;
@@ -51,6 +59,10 @@ interface StepConfig {
51
59
  mode?: 'create' | 'edit' | 'view';
52
60
  config?: FormConfig;
53
61
  schemaSource?: 'resource' | 'filter';
62
+ /** Explicit discovery URL. The stepper never infers schema authority. */
63
+ schemaUrl?: string;
64
+ apiEndpointKey?: ApiEndpoint | string;
65
+ apiUrlEntry?: ApiUrlEntry | null;
54
66
  formId?: string;
55
67
  };
56
68
  /** Rich editorial content rendered before the step form. */
@@ -100,10 +112,13 @@ interface StepperMetadata {
100
112
  }
101
113
  declare class PraxisStepper implements OnInit, AfterViewInit, OnDestroy {
102
114
  stepLabelTpl?: TemplateRef<any>;
115
+ private materialStepper?;
103
116
  _config: _angular_core.WritableSignal<StepperMetadata | null>;
104
117
  private _selectedIndex;
105
118
  private _formGroups;
119
+ private _formComponents;
106
120
  private _formValidity;
121
+ private _formPending;
107
122
  private readonly hostElement;
108
123
  private readonly renderer;
109
124
  private appliedHeaderClasses;
@@ -154,6 +169,19 @@ declare class PraxisStepper implements OnInit, AfterViewInit, OnDestroy {
154
169
  stepId?: string;
155
170
  event: FormValueChangeEvent;
156
171
  }>;
172
+ /** Metadata-only determination lifecycle forwarded from the child form. */
173
+ stepReactiveDeterminationExecuted: EventEmitter<{
174
+ stepIndex: number;
175
+ stepId?: string;
176
+ event: ReactiveDeterminationExecutionEvent;
177
+ }>;
178
+ stepReactiveDeterminationPendingChange: EventEmitter<{
179
+ stepIndex: number;
180
+ stepId?: string;
181
+ pending: boolean;
182
+ }>;
183
+ /** Aggregate stability; settled-unsatisfied is intentionally distinct from success. */
184
+ reactiveDeterminationStabilityChange: EventEmitter<StepperReactiveDeterminationStabilityChange>;
157
185
  stepperContext?: Record<string, any>;
158
186
  private readonly settings;
159
187
  private readonly storage;
@@ -161,6 +189,7 @@ declare class PraxisStepper implements OnInit, AfterViewInit, OnDestroy {
161
189
  private readonly logger;
162
190
  private readonly route;
163
191
  private readonly cdr;
192
+ private reactiveDeterminationStabilitySignature;
164
193
  private readonly aiApi;
165
194
  private readonly assistantSessions;
166
195
  private readonly aiTurnOrchestrator;
@@ -214,9 +243,13 @@ declare class PraxisStepper implements OnInit, AfterViewInit, OnDestroy {
214
243
  next(): void;
215
244
  prev(): void;
216
245
  reset(): void;
246
+ private advanceTo;
217
247
  previous(): void;
218
- onFormReady(stepIndex: number, ev: FormReadyEvent): void;
248
+ onFormReady(stepIndex: number, ev: FormReadyEvent, component?: PraxisDynamicForm): void;
219
249
  onFormValueChange(stepIndex: number, ev: FormValueChangeEvent): void;
250
+ onReactiveDeterminationExecuted(stepIndex: number, event: ReactiveDeterminationExecutionEvent): void;
251
+ onReactiveDeterminationPendingChange(stepIndex: number, pending: boolean): void;
252
+ private emitReactiveDeterminationStability;
220
253
  formGroupFor(i: number): FormGroup | undefined;
221
254
  computedCompleted(i: number, step: StepConfig): boolean;
222
255
  computedHasError(i: number, step: StepConfig): boolean;
@@ -256,6 +289,7 @@ declare class PraxisStepper implements OnInit, AfterViewInit, OnDestroy {
256
289
  onNext(i: number): Promise<void>;
257
290
  validateStep(i?: number): Promise<boolean>;
258
291
  nextWithValidation(i?: number): Promise<boolean>;
292
+ private hasBlockingReactiveDetermination;
259
293
  onPrev(): void;
260
294
  onAnimationDone(): void;
261
295
  private applyServerErrors;
@@ -272,7 +306,7 @@ declare class PraxisStepper implements OnInit, AfterViewInit, OnDestroy {
272
306
  private parseClassList;
273
307
  private resolveCssTokenName;
274
308
  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>;
309
+ 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"; "reactiveDeterminationStabilityChange": "reactiveDeterminationStabilityChange"; "animationDone": "animationDone"; "selectionChange": "selectionChange"; }, ["stepLabelTpl"], ["*"], true, never>;
276
310
  }
277
311
 
278
312
  declare const PRAXIS_STEPPER_COMPONENT_METADATA: ComponentDocMeta;
@@ -460,6 +494,14 @@ interface WizardCtaConfig {
460
494
  interface WizardStepFormConfig {
461
495
  formId?: string;
462
496
  config: FormConfig;
497
+ resourcePath?: string;
498
+ resourceId?: string | number;
499
+ mode?: 'create' | 'edit' | 'view';
500
+ schemaSource?: 'resource' | 'filter';
501
+ /** Explicit schema authority; the wizard never derives it. */
502
+ schemaUrl?: string;
503
+ apiEndpointKey?: ApiEndpoint | string;
504
+ apiUrlEntry?: ApiUrlEntry | null;
463
505
  }
464
506
  interface WizardStepConfig {
465
507
  id: string;
@@ -587,4 +629,4 @@ declare const STEPPER_AI_CAPABILITIES: CapabilityCatalog;
587
629
  declare const PRAXIS_STEPPER_AUTHORING_MANIFEST: ComponentAuthoringManifest;
588
630
 
589
631
  export { FT_WIZARD_CONFIG, FT_WIZARD_JSON, PRAXIS_STEPPER_AUTHORING_MANIFEST, PRAXIS_STEPPER_COMPONENT_METADATA, PRAXIS_WIZARD_BENEFITS_METADATA, PRAXIS_WIZARD_CONTENT_METADATA, PRAXIS_WIZARD_DIVIDER_METADATA, PRAXIS_WIZARD_NOTICE_METADATA, PraxisStepper, PraxisStepperConfigEditor, PraxisStepperWidgetConfigEditor, PraxisWizardFormComponent, STEPPER_AI_CAPABILITIES, providePraxisStepperMetadata };
590
- export type { Capability, CapabilityCatalog, CapabilityCategory, PraxisStepperWidgetEditorInputs, PraxisStepperWidgetEditorValue, StepConfig, StepHeaderPosition, StepOrientation, StepperMetadata, ValueKind, WizardBenefitItem, WizardBenefitsBlock, WizardBlock, WizardBlockBase, WizardBlockPlacement, WizardCard, WizardContentBlock, WizardCtaAction, WizardCtaConfig, WizardDividerBlock, WizardFormConfig, WizardInlineNoticeBlock, WizardPreferencesConfig, WizardProgressConfig, WizardSecondaryAction, WizardStepConfig, WizardStepFormConfig, WizardStepZones };
632
+ export type { Capability, CapabilityCatalog, CapabilityCategory, PraxisStepperWidgetEditorInputs, PraxisStepperWidgetEditorValue, StepConfig, StepHeaderPosition, StepOrientation, StepperMetadata, StepperReactiveDeterminationStabilityChange, StepperReactiveDeterminationStabilityStatus, ValueKind, WizardBenefitItem, WizardBenefitsBlock, WizardBlock, WizardBlockBase, WizardBlockPlacement, WizardCard, WizardContentBlock, WizardCtaAction, WizardCtaConfig, WizardDividerBlock, WizardFormConfig, WizardInlineNoticeBlock, WizardPreferencesConfig, WizardProgressConfig, WizardSecondaryAction, WizardStepConfig, WizardStepFormConfig, WizardStepZones };