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

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,7 +61,7 @@ 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).
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
65
 
66
66
  ```ts
67
67
  const config: StepperMetadata = {
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": "1.0.0",
3
- "generatedAt": "2026-08-13T20:07:32.063Z",
3
+ "generatedAt": "2026-08-14T02:17:07.973Z",
4
4
  "packageName": "@praxisui/stepper",
5
- "packageVersion": "9.0.5-rc.14",
5
+ "packageVersion": "9.0.5-rc.16",
6
6
  "sourceRegistry": "praxis-component-registry-ingestion",
7
7
  "sourceRegistryVersion": "1.0.0",
8
8
  "componentCount": 1,
@@ -133,6 +133,12 @@
133
133
  "type": "{ stepId?: string; stepIndex: number; pending: boolean }",
134
134
  "required": false,
135
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"
136
142
  }
137
143
  ],
138
144
  "configSchemaId": null,
@@ -2140,9 +2146,9 @@
2140
2146
  {
2141
2147
  "chunkIndex": 0,
2142
2148
  "chunkKind": "summary",
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",
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",
2144
2150
  "sourcePointer": "projects/praxis-stepper/src/lib/praxis-stepper.metadata.ts",
2145
- "contentHash": "89fa6ee9abc0b7a70beb7bdf1692cdf4a53fbded066cca36874f736e7ba5903a",
2151
+ "contentHash": "45d94ab8764dc92a68f79332305178436a43403578fa626846dbc9f163684a37",
2146
2152
  "sourceKind": "component_definition",
2147
2153
  "sourceId": "praxis-stepper",
2148
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
  };
@@ -3427,8 +3429,8 @@ class PraxisStepper {
3427
3429
  appliedHeaderClasses = [];
3428
3430
  appliedTokenNames = [];
3429
3431
  // CTA models for empty state
3430
- primaryCta = { label: 'Configurar Stepper', icon: 'tune', color: 'primary', action: () => this.openEditor() };
3431
- 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(), },];
3432
3434
  // API de entrada
3433
3435
  stepperId;
3434
3436
  componentInstanceId;
@@ -3477,6 +3479,8 @@ class PraxisStepper {
3477
3479
  /** Metadata-only determination lifecycle forwarded from the child form. */
3478
3480
  stepReactiveDeterminationExecuted = new EventEmitter();
3479
3481
  stepReactiveDeterminationPendingChange = new EventEmitter();
3482
+ /** Aggregate stability; settled-unsatisfied is intentionally distinct from success. */
3483
+ reactiveDeterminationStabilityChange = new EventEmitter();
3480
3484
  stepperContext;
3481
3485
  settings = inject(SettingsPanelService);
3482
3486
  storage = inject(ASYNC_CONFIG_STORAGE);
@@ -3489,6 +3493,7 @@ class PraxisStepper {
3489
3493
  return undefined;
3490
3494
  } })();
3491
3495
  cdr = inject(ChangeDetectorRef);
3496
+ reactiveDeterminationStabilitySignature = '';
3492
3497
  aiApi = inject(AiBackendApiService);
3493
3498
  assistantSessions = inject(PraxisAssistantSessionRegistryService);
3494
3499
  aiTurnOrchestrator = inject(PraxisAssistantTurnOrchestratorService);
@@ -3565,8 +3570,8 @@ class PraxisStepper {
3565
3570
  }
3566
3571
  };
3567
3572
  isNextDisabled(i) {
3568
- return this._formPending.get(i) === true ||
3569
- (this.linear() && this._formValidity.get(i) === false);
3573
+ return (this.hasBlockingReactiveDetermination(i) ||
3574
+ (this.linear() && this._formValidity.get(i) === false));
3570
3575
  }
3571
3576
  clampIndex(idx) {
3572
3577
  const len = this.steps().length;
@@ -3590,7 +3595,7 @@ class PraxisStepper {
3590
3595
  onSelectionChange(ev) {
3591
3596
  const idx = this.clampIndex(ev?.selectedIndex ?? 0);
3592
3597
  const current = this._selectedIndex();
3593
- if (idx !== current && this._formPending.get(current) === true) {
3598
+ if (idx !== current && this.hasBlockingReactiveDetermination(current)) {
3594
3599
  if (this.materialStepper)
3595
3600
  this.materialStepper.selectedIndex = current;
3596
3601
  this.cdr.markForCheck();
@@ -3603,7 +3608,9 @@ class PraxisStepper {
3603
3608
  // API programática básica
3604
3609
  goTo(index) {
3605
3610
  const clamped = this.clampIndex(index);
3606
- if (clamped !== this._selectedIndex() && this._formPending.get(this._selectedIndex()) === true) {
3611
+ if (clamped !==
3612
+ this._selectedIndex() &&
3613
+ this.hasBlockingReactiveDetermination(this._selectedIndex())) {
3607
3614
  return;
3608
3615
  }
3609
3616
  this.advanceTo(clamped);
@@ -3611,7 +3618,7 @@ class PraxisStepper {
3611
3618
  next() {
3612
3619
  const curr = this._selectedIndex();
3613
3620
  const len = this.steps().length;
3614
- if (curr < len - 1 && this._formPending.get(curr) !== true)
3621
+ if (curr < len - 1 && !this.hasBlockingReactiveDetermination(curr))
3615
3622
  this.advanceTo(curr + 1);
3616
3623
  }
3617
3624
  prev() {
@@ -3653,6 +3660,7 @@ class PraxisStepper {
3653
3660
  stepId: this.steps()[stepIndex]?.id,
3654
3661
  event,
3655
3662
  });
3663
+ this.emitReactiveDeterminationStability();
3656
3664
  }
3657
3665
  onReactiveDeterminationPendingChange(stepIndex, pending) {
3658
3666
  this._formPending.set(stepIndex, pending);
@@ -3661,8 +3669,25 @@ class PraxisStepper {
3661
3669
  stepId: this.steps()[stepIndex]?.id,
3662
3670
  pending,
3663
3671
  });
3672
+ this.emitReactiveDeterminationStability();
3664
3673
  this.cdr.markForCheck();
3665
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
+ }
3666
3691
  formGroupFor(i) {
3667
3692
  return this._formGroups.get(i);
3668
3693
  }
@@ -3711,12 +3736,12 @@ class PraxisStepper {
3711
3736
  };
3712
3737
  }
3713
3738
  openEditor() {
3714
- const cfg = this._config() || { steps: [], orientation: 'horizontal', headerPosition: 'top', linear: false };
3739
+ const cfg = this._config() || { steps: [], orientation: 'horizontal', headerPosition: 'top', linear: false, };
3715
3740
  const key = this.storageKey() || this.stepperId || 'default';
3716
3741
  const ref = this.settings.open({
3717
3742
  id: `praxis-stepper-editor:${key}`,
3718
3743
  title: 'Configurar Stepper',
3719
- content: { component: PraxisStepperConfigEditor, inputs: { config: cfg } },
3744
+ content: { component: PraxisStepperConfigEditor, inputs: { config: cfg }, },
3720
3745
  });
3721
3746
  const apply = (value) => {
3722
3747
  const nextCfg = value?.config || value;
@@ -3939,7 +3964,7 @@ class PraxisStepper {
3939
3964
  'steps',
3940
3965
  'selectedIndex',
3941
3966
  'linear',
3942
- 'orientation',
3967
+ 'orientation'
3943
3968
  ],
3944
3969
  },
3945
3970
  capabilityRefs: [
@@ -3977,18 +4002,18 @@ class PraxisStepper {
3977
4002
  });
3978
4003
  }
3979
4004
  hasAiAssistantSessionState() {
3980
- return !!this.aiAssistantPrompt.trim()
4005
+ return (!!this.aiAssistantPrompt.trim()
3981
4006
  || !!this.aiAssistantViewState?.messages?.length
3982
4007
  || !!this.aiAssistantViewState?.quickReplies?.length
3983
4008
  || !!this.aiAssistantViewState?.pendingPatch
3984
4009
  || !!this.aiAssistantViewState?.statusText?.trim()
3985
- || !!this.aiAssistantViewState?.errorText?.trim();
4010
+ || !!this.aiAssistantViewState?.errorText?.trim());
3986
4011
  }
3987
4012
  resolveAiAssistantSessionId() {
3988
4013
  return `stepper:${this.resolveAiAssistantRouteKey()}:${this.resolveAiAssistantOwnerId()}`;
3989
4014
  }
3990
4015
  resolveAiAssistantOwnerId() {
3991
- return (this.componentInstanceId || this.safeAiAssistantStepperId() || 'stepper').trim() || 'stepper';
4016
+ return ((this.componentInstanceId || this.safeAiAssistantStepperId() || 'stepper').trim() || 'stepper');
3992
4017
  }
3993
4018
  safeAiAssistantStepperId() {
3994
4019
  return String(this.stepperId || '').trim();
@@ -4047,19 +4072,19 @@ class PraxisStepper {
4047
4072
  stepCount: steps.length,
4048
4073
  formStepCount: steps.filter((step) => !!step.form).length,
4049
4074
  widgetStepCount: steps.filter((step) => Array.isArray(step.widgets) && step.widgets.length > 0).length,
4050
- richContentStepCount: steps.filter((step) => (this.hasRichContent(step.stepBlocksBeforeForm)
4051
- || this.hasRichContent(step.stepBlocksAfterForm))).length,
4075
+ richContentStepCount: steps.filter((step) => this.hasRichContent(step.stepBlocksBeforeForm)
4076
+ || this.hasRichContent(step.stepBlocksAfterForm)).length,
4052
4077
  };
4053
4078
  }
4054
4079
  // CTA helpers
4055
4080
  addFirstStep() {
4056
- const current = this._config() || { steps: [], orientation: 'horizontal', headerPosition: 'top', linear: false };
4081
+ const current = this._config() || { steps: [], orientation: 'horizontal', headerPosition: 'top', linear: false, };
4057
4082
  if ((current.steps || []).length > 0)
4058
4083
  return;
4059
4084
  const next = {
4060
4085
  ...current,
4061
4086
  steps: [
4062
- { 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.', },
4063
4088
  ],
4064
4089
  };
4065
4090
  this._config.set(next);
@@ -4074,7 +4099,7 @@ class PraxisStepper {
4074
4099
  }
4075
4100
  async validateStep(i = this.selectedIndexComputed()) {
4076
4101
  const childForm = this._formComponents.get(i);
4077
- if (childForm?.hasPendingReactiveDeterminations()) {
4102
+ if (childForm && this.hasBlockingReactiveDetermination(i)) {
4078
4103
  const stable = await childForm.waitForReactiveDeterminations();
4079
4104
  if (!stable)
4080
4105
  return false;
@@ -4095,7 +4120,7 @@ class PraxisStepper {
4095
4120
  const fg = this._formGroups.get(i);
4096
4121
  const data = fg?.getRawValue();
4097
4122
  if (this.serverValidate) {
4098
- 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, });
4099
4124
  if (!res.ok) {
4100
4125
  this.applyServerErrors(fg, res.fieldErrors, res.formErrors);
4101
4126
  // Atualizar erro visual
@@ -4103,7 +4128,7 @@ class PraxisStepper {
4103
4128
  this._formValidity.set(i, false);
4104
4129
  return false;
4105
4130
  }
4106
- if (childForm?.hasPendingReactiveDeterminations()) {
4131
+ if (childForm && this.hasBlockingReactiveDetermination(i)) {
4107
4132
  const stable = await childForm.waitForReactiveDeterminations();
4108
4133
  if (!stable)
4109
4134
  return false;
@@ -4121,6 +4146,13 @@ class PraxisStepper {
4121
4146
  this.advanceTo(current + 1);
4122
4147
  return true;
4123
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
+ }
4124
4156
  onPrev() { this.prev(); }
4125
4157
  onAnimationDone() { this.animationDone.emit(); }
4126
4158
  applyServerErrors(fg, fieldErrors, formErrors) {
@@ -4242,7 +4274,7 @@ class PraxisStepper {
4242
4274
  return name.startsWith('--') ? name : `--${name}`;
4243
4275
  }
4244
4276
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisStepper, deps: [], target: i0.ɵɵFactoryTarget.Component });
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: `
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: `
4246
4278
  @if (enableCustomization) {
4247
4279
  <div class="stepper-ai-assistant">
4248
4280
  <button
@@ -4269,7 +4301,10 @@ class PraxisStepper {
4269
4301
  [prompt]="aiAssistantPrompt"
4270
4302
  [statusText]="aiAssistantViewState.statusText"
4271
4303
  [errorText]="aiAssistantViewState.errorText"
4272
- [busy]="aiAssistantViewState.state === 'processing' || aiAssistantViewState.state === 'applying'"
4304
+ [busy]="
4305
+ aiAssistantViewState.state === 'processing' ||
4306
+ aiAssistantViewState.state === 'applying'
4307
+ "
4273
4308
  [canApply]="aiAssistantViewState.canApply"
4274
4309
  [labels]="aiAssistantLabels"
4275
4310
  [layout]="aiAssistantLayout"
@@ -4351,7 +4386,9 @@ class PraxisStepper {
4351
4386
  <div [class]="contentClassList()">
4352
4387
  @if (hasRichContent(step.stepBlocksBeforeForm)) {
4353
4388
  <praxis-rich-content
4354
- [document]="step.stepBlocksBeforeForm || emptyStepRichContentDocument"
4389
+ [document]="
4390
+ step.stepBlocksBeforeForm || emptyStepRichContentDocument
4391
+ "
4355
4392
  [context]="getStepRichContentContext(i)"
4356
4393
  rootClassName="pdx-step-rich-content pdx-step-rich-content--before"
4357
4394
  ></praxis-rich-content>
@@ -4370,13 +4407,19 @@ class PraxisStepper {
4370
4407
  [formId]="f.formId"
4371
4408
  (formReady)="onFormReady(i, $event, stepForm)"
4372
4409
  (valueChange)="onFormValueChange(i, $event)"
4373
- (reactiveDeterminationExecuted)="onReactiveDeterminationExecuted(i, $event)"
4374
- (reactiveDeterminationPendingChange)="onReactiveDeterminationPendingChange(i, $event)"
4410
+ (reactiveDeterminationExecuted)="
4411
+ onReactiveDeterminationExecuted(i, $event)
4412
+ "
4413
+ (reactiveDeterminationPendingChange)="
4414
+ onReactiveDeterminationPendingChange(i, $event)
4415
+ "
4375
4416
  ></praxis-dynamic-form>
4376
4417
  }
4377
4418
  @if (hasRichContent(step.stepBlocksAfterForm)) {
4378
4419
  <praxis-rich-content
4379
- [document]="step.stepBlocksAfterForm || emptyStepRichContentDocument"
4420
+ [document]="
4421
+ step.stepBlocksAfterForm || emptyStepRichContentDocument
4422
+ "
4380
4423
  [context]="getStepRichContentContext(i)"
4381
4424
  rootClassName="pdx-step-rich-content pdx-step-rich-content--after"
4382
4425
  ></praxis-rich-content>
@@ -4387,7 +4430,8 @@ class PraxisStepper {
4387
4430
  [context]="stepperContext"
4388
4431
  [strictValidation]="true"
4389
4432
  [autoWireOutputs]="true"
4390
- (widgetEvent)="onChildWidgetEvent(i, wd, $event)"></ng-container>
4433
+ (widgetEvent)="onChildWidgetEvent(i, wd, $event)"
4434
+ ></ng-container>
4391
4435
  }
4392
4436
  @if (isStepEmpty(step)) {
4393
4437
  <praxis-empty-state-card
@@ -4395,7 +4439,11 @@ class PraxisStepper {
4395
4439
  icon="dashboard_customize"
4396
4440
  title="Sem conteúdo nesta etapa"
4397
4441
  description="Adicione um formulário ou widgets a esta etapa, ou abra o editor para configurar."
4398
- [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
+ }"
4399
4447
  ></praxis-empty-state-card>
4400
4448
  }
4401
4449
  </div>
@@ -4405,7 +4453,12 @@ class PraxisStepper {
4405
4453
  @if (selectedIndexComputed() > 0) {
4406
4454
  @switch (navVariant()) {
4407
4455
  @case ('flat') {
4408
- <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
+ >
4409
4462
  @if (navPrevIcon(); as ic) {
4410
4463
  <mat-icon [praxisIcon]="ic"></mat-icon>
4411
4464
  }
@@ -4413,7 +4466,12 @@ class PraxisStepper {
4413
4466
  </button>
4414
4467
  }
4415
4468
  @case ('stroked') {
4416
- <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
+ >
4417
4475
  @if (navPrevIcon(); as ic) {
4418
4476
  <mat-icon [praxisIcon]="ic"></mat-icon>
4419
4477
  }
@@ -4421,7 +4479,12 @@ class PraxisStepper {
4421
4479
  </button>
4422
4480
  }
4423
4481
  @case ('raised') {
4424
- <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
+ >
4425
4488
  @if (navPrevIcon(); as ic) {
4426
4489
  <mat-icon [praxisIcon]="ic"></mat-icon>
4427
4490
  }
@@ -4429,7 +4492,12 @@ class PraxisStepper {
4429
4492
  </button>
4430
4493
  }
4431
4494
  @default {
4432
- <button mat-button [color]="navColor()" type="button" (click)="onPrev()">
4495
+ <button
4496
+ mat-button
4497
+ [color]="navColor()"
4498
+ type="button"
4499
+ (click)="onPrev()"
4500
+ >
4433
4501
  @if (navPrevIcon(); as ic) {
4434
4502
  <mat-icon [praxisIcon]="ic"></mat-icon>
4435
4503
  }
@@ -4441,7 +4509,13 @@ class PraxisStepper {
4441
4509
  <!-- NEXT button -->
4442
4510
  @switch (navVariant()) {
4443
4511
  @case ('flat') {
4444
- <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
+ >
4445
4519
  {{ navNextLabel() }}
4446
4520
  @if (navNextIcon(); as ic) {
4447
4521
  <mat-icon [praxisIcon]="ic"></mat-icon>
@@ -4449,7 +4523,13 @@ class PraxisStepper {
4449
4523
  </button>
4450
4524
  }
4451
4525
  @case ('stroked') {
4452
- <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
+ >
4453
4533
  {{ navNextLabel() }}
4454
4534
  @if (navNextIcon(); as ic) {
4455
4535
  <mat-icon [praxisIcon]="ic"></mat-icon>
@@ -4457,7 +4537,13 @@ class PraxisStepper {
4457
4537
  </button>
4458
4538
  }
4459
4539
  @case ('raised') {
4460
- <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
+ >
4461
4547
  {{ navNextLabel() }}
4462
4548
  @if (navNextIcon(); as ic) {
4463
4549
  <mat-icon [praxisIcon]="ic"></mat-icon>
@@ -4465,7 +4551,13 @@ class PraxisStepper {
4465
4551
  </button>
4466
4552
  }
4467
4553
  @default {
4468
- <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
+ >
4469
4561
  {{ navNextLabel() }}
4470
4562
  @if (navNextIcon(); as ic) {
4471
4563
  <mat-icon [praxisIcon]="ic"></mat-icon>
@@ -4498,12 +4590,12 @@ class PraxisStepper {
4498
4590
  <mat-icon fontIcon="edit"></mat-icon>
4499
4591
  </button>
4500
4592
  }
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 });
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", "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 });
4502
4594
  }
4503
4595
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisStepper, decorators: [{
4504
4596
  type: Component,
4505
- args: [{ selector: 'praxis-stepper', standalone: true, imports: [CommonModule, ReactiveFormsModule, MatStepperModule, MatButtonModule, MatIconModule, PraxisIconDirective, PraxisDynamicForm, DynamicWidgetLoaderDirective, EmptyStateCardComponent, PraxisAiAssistantShellComponent, PraxisRichContent], host: {
4506
- '[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()',
4507
4599
  }, template: `
4508
4600
  @if (enableCustomization) {
4509
4601
  <div class="stepper-ai-assistant">
@@ -4531,7 +4623,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
4531
4623
  [prompt]="aiAssistantPrompt"
4532
4624
  [statusText]="aiAssistantViewState.statusText"
4533
4625
  [errorText]="aiAssistantViewState.errorText"
4534
- [busy]="aiAssistantViewState.state === 'processing' || aiAssistantViewState.state === 'applying'"
4626
+ [busy]="
4627
+ aiAssistantViewState.state === 'processing' ||
4628
+ aiAssistantViewState.state === 'applying'
4629
+ "
4535
4630
  [canApply]="aiAssistantViewState.canApply"
4536
4631
  [labels]="aiAssistantLabels"
4537
4632
  [layout]="aiAssistantLayout"
@@ -4613,7 +4708,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
4613
4708
  <div [class]="contentClassList()">
4614
4709
  @if (hasRichContent(step.stepBlocksBeforeForm)) {
4615
4710
  <praxis-rich-content
4616
- [document]="step.stepBlocksBeforeForm || emptyStepRichContentDocument"
4711
+ [document]="
4712
+ step.stepBlocksBeforeForm || emptyStepRichContentDocument
4713
+ "
4617
4714
  [context]="getStepRichContentContext(i)"
4618
4715
  rootClassName="pdx-step-rich-content pdx-step-rich-content--before"
4619
4716
  ></praxis-rich-content>
@@ -4632,13 +4729,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
4632
4729
  [formId]="f.formId"
4633
4730
  (formReady)="onFormReady(i, $event, stepForm)"
4634
4731
  (valueChange)="onFormValueChange(i, $event)"
4635
- (reactiveDeterminationExecuted)="onReactiveDeterminationExecuted(i, $event)"
4636
- (reactiveDeterminationPendingChange)="onReactiveDeterminationPendingChange(i, $event)"
4732
+ (reactiveDeterminationExecuted)="
4733
+ onReactiveDeterminationExecuted(i, $event)
4734
+ "
4735
+ (reactiveDeterminationPendingChange)="
4736
+ onReactiveDeterminationPendingChange(i, $event)
4737
+ "
4637
4738
  ></praxis-dynamic-form>
4638
4739
  }
4639
4740
  @if (hasRichContent(step.stepBlocksAfterForm)) {
4640
4741
  <praxis-rich-content
4641
- [document]="step.stepBlocksAfterForm || emptyStepRichContentDocument"
4742
+ [document]="
4743
+ step.stepBlocksAfterForm || emptyStepRichContentDocument
4744
+ "
4642
4745
  [context]="getStepRichContentContext(i)"
4643
4746
  rootClassName="pdx-step-rich-content pdx-step-rich-content--after"
4644
4747
  ></praxis-rich-content>
@@ -4649,7 +4752,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
4649
4752
  [context]="stepperContext"
4650
4753
  [strictValidation]="true"
4651
4754
  [autoWireOutputs]="true"
4652
- (widgetEvent)="onChildWidgetEvent(i, wd, $event)"></ng-container>
4755
+ (widgetEvent)="onChildWidgetEvent(i, wd, $event)"
4756
+ ></ng-container>
4653
4757
  }
4654
4758
  @if (isStepEmpty(step)) {
4655
4759
  <praxis-empty-state-card
@@ -4657,7 +4761,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
4657
4761
  icon="dashboard_customize"
4658
4762
  title="Sem conteúdo nesta etapa"
4659
4763
  description="Adicione um formulário ou widgets a esta etapa, ou abra o editor para configurar."
4660
- [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
+ }"
4661
4769
  ></praxis-empty-state-card>
4662
4770
  }
4663
4771
  </div>
@@ -4667,7 +4775,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
4667
4775
  @if (selectedIndexComputed() > 0) {
4668
4776
  @switch (navVariant()) {
4669
4777
  @case ('flat') {
4670
- <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
+ >
4671
4784
  @if (navPrevIcon(); as ic) {
4672
4785
  <mat-icon [praxisIcon]="ic"></mat-icon>
4673
4786
  }
@@ -4675,7 +4788,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
4675
4788
  </button>
4676
4789
  }
4677
4790
  @case ('stroked') {
4678
- <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
+ >
4679
4797
  @if (navPrevIcon(); as ic) {
4680
4798
  <mat-icon [praxisIcon]="ic"></mat-icon>
4681
4799
  }
@@ -4683,7 +4801,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
4683
4801
  </button>
4684
4802
  }
4685
4803
  @case ('raised') {
4686
- <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
+ >
4687
4810
  @if (navPrevIcon(); as ic) {
4688
4811
  <mat-icon [praxisIcon]="ic"></mat-icon>
4689
4812
  }
@@ -4691,7 +4814,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
4691
4814
  </button>
4692
4815
  }
4693
4816
  @default {
4694
- <button mat-button [color]="navColor()" type="button" (click)="onPrev()">
4817
+ <button
4818
+ mat-button
4819
+ [color]="navColor()"
4820
+ type="button"
4821
+ (click)="onPrev()"
4822
+ >
4695
4823
  @if (navPrevIcon(); as ic) {
4696
4824
  <mat-icon [praxisIcon]="ic"></mat-icon>
4697
4825
  }
@@ -4703,7 +4831,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
4703
4831
  <!-- NEXT button -->
4704
4832
  @switch (navVariant()) {
4705
4833
  @case ('flat') {
4706
- <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
+ >
4707
4841
  {{ navNextLabel() }}
4708
4842
  @if (navNextIcon(); as ic) {
4709
4843
  <mat-icon [praxisIcon]="ic"></mat-icon>
@@ -4711,7 +4845,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
4711
4845
  </button>
4712
4846
  }
4713
4847
  @case ('stroked') {
4714
- <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
+ >
4715
4855
  {{ navNextLabel() }}
4716
4856
  @if (navNextIcon(); as ic) {
4717
4857
  <mat-icon [praxisIcon]="ic"></mat-icon>
@@ -4719,7 +4859,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
4719
4859
  </button>
4720
4860
  }
4721
4861
  @case ('raised') {
4722
- <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
+ >
4723
4869
  {{ navNextLabel() }}
4724
4870
  @if (navNextIcon(); as ic) {
4725
4871
  <mat-icon [praxisIcon]="ic"></mat-icon>
@@ -4727,7 +4873,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
4727
4873
  </button>
4728
4874
  }
4729
4875
  @default {
4730
- <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
+ >
4731
4883
  {{ navNextLabel() }}
4732
4884
  @if (navNextIcon(); as ic) {
4733
4885
  <mat-icon [praxisIcon]="ic"></mat-icon>
@@ -4760,7 +4912,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
4760
4912
  <mat-icon fontIcon="edit"></mat-icon>
4761
4913
  </button>
4762
4914
  }
4763
- `, 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"] }]
4764
4916
  }], propDecorators: { stepLabelTpl: [{
4765
4917
  type: ContentChild,
4766
4918
  args: ['stepLabelTpl', { read: TemplateRef }]
@@ -4800,6 +4952,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
4800
4952
  type: Output
4801
4953
  }], stepReactiveDeterminationPendingChange: [{
4802
4954
  type: Output
4955
+ }], reactiveDeterminationStabilityChange: [{
4956
+ type: Output
4803
4957
  }], stepperContext: [{
4804
4958
  type: Input
4805
4959
  }], animationDone: [{
@@ -5118,6 +5272,7 @@ const PRAXIS_STEPPER_COMPONENT_METADATA = {
5118
5272
  { name: 'stepFormValueChange', type: '{ stepId?: string; stepIndex: number; event: FormValueChangeEvent }', label: 'Form value change (por etapa)' },
5119
5273
  { name: 'stepReactiveDeterminationExecuted', type: '{ stepId?: string; stepIndex: number; event: ReactiveDeterminationExecutionEvent }', label: 'Evidencia metadata-only por etapa' },
5120
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' },
5121
5276
  ],
5122
5277
  actions: [
5123
5278
  {
@@ -6053,7 +6208,7 @@ class PraxisWizardFormComponent {
6053
6208
  ></praxis-wizard-cta-bar>
6054
6209
  </mat-card>
6055
6210
  </section>
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 });
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 });
6057
6212
  }
6058
6213
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisWizardFormComponent, decorators: [{
6059
6214
  type: Component,
package/package.json CHANGED
@@ -1,22 +1,22 @@
1
1
  {
2
2
  "name": "@praxisui/stepper",
3
- "version": "9.0.5-rc.14",
3
+ "version": "9.0.5-rc.16",
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.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",
10
+ "@praxisui/core": "^9.0.5-rc.16",
11
+ "@praxisui/dynamic-form": "^9.0.5-rc.16",
12
+ "@praxisui/rich-content": "^9.0.5-rc.16",
13
+ "@praxisui/settings-panel": "^9.0.5-rc.16",
14
+ "@praxisui/list": "^9.0.5-rc.16",
15
+ "@praxisui/files-upload": "^9.0.5-rc.16",
16
+ "@praxisui/page-builder": "^9.0.5-rc.16",
17
17
  "@angular/forms": "^21.0.0",
18
18
  "@angular/router": "^21.0.0",
19
- "@praxisui/ai": "^9.0.5-rc.14",
19
+ "@praxisui/ai": "^9.0.5-rc.16",
20
20
  "rxjs": "~7.8.0"
21
21
  },
22
22
  "dependencies": {
@@ -34,6 +34,13 @@ declare class StepperAiAdapter extends BaseAiAdapter<StepperMetadata> {
34
34
 
35
35
  type StepOrientation = 'horizontal' | 'vertical';
36
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
+ }
37
44
  interface StepConfig {
38
45
  id?: string;
39
46
  label: string;
@@ -173,6 +180,8 @@ declare class PraxisStepper implements OnInit, AfterViewInit, OnDestroy {
173
180
  stepId?: string;
174
181
  pending: boolean;
175
182
  }>;
183
+ /** Aggregate stability; settled-unsatisfied is intentionally distinct from success. */
184
+ reactiveDeterminationStabilityChange: EventEmitter<StepperReactiveDeterminationStabilityChange>;
176
185
  stepperContext?: Record<string, any>;
177
186
  private readonly settings;
178
187
  private readonly storage;
@@ -180,6 +189,7 @@ declare class PraxisStepper implements OnInit, AfterViewInit, OnDestroy {
180
189
  private readonly logger;
181
190
  private readonly route;
182
191
  private readonly cdr;
192
+ private reactiveDeterminationStabilitySignature;
183
193
  private readonly aiApi;
184
194
  private readonly assistantSessions;
185
195
  private readonly aiTurnOrchestrator;
@@ -239,6 +249,7 @@ declare class PraxisStepper implements OnInit, AfterViewInit, OnDestroy {
239
249
  onFormValueChange(stepIndex: number, ev: FormValueChangeEvent): void;
240
250
  onReactiveDeterminationExecuted(stepIndex: number, event: ReactiveDeterminationExecutionEvent): void;
241
251
  onReactiveDeterminationPendingChange(stepIndex: number, pending: boolean): void;
252
+ private emitReactiveDeterminationStability;
242
253
  formGroupFor(i: number): FormGroup | undefined;
243
254
  computedCompleted(i: number, step: StepConfig): boolean;
244
255
  computedHasError(i: number, step: StepConfig): boolean;
@@ -278,6 +289,7 @@ declare class PraxisStepper implements OnInit, AfterViewInit, OnDestroy {
278
289
  onNext(i: number): Promise<void>;
279
290
  validateStep(i?: number): Promise<boolean>;
280
291
  nextWithValidation(i?: number): Promise<boolean>;
292
+ private hasBlockingReactiveDetermination;
281
293
  onPrev(): void;
282
294
  onAnimationDone(): void;
283
295
  private applyServerErrors;
@@ -294,7 +306,7 @@ declare class PraxisStepper implements OnInit, AfterViewInit, OnDestroy {
294
306
  private parseClassList;
295
307
  private resolveCssTokenName;
296
308
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<PraxisStepper, 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>;
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>;
298
310
  }
299
311
 
300
312
  declare const PRAXIS_STEPPER_COMPONENT_METADATA: ComponentDocMeta;
@@ -617,4 +629,4 @@ declare const STEPPER_AI_CAPABILITIES: CapabilityCatalog;
617
629
  declare const PRAXIS_STEPPER_AUTHORING_MANIFEST: ComponentAuthoringManifest;
618
630
 
619
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 };
620
- 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 };